Merge "Use RGBA16F layers when wide color gamut rendering is on" into oc-dr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
9ae7bb7aa3
@@ -32,7 +32,8 @@ namespace uirenderer {
|
||||
OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) {
|
||||
LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
|
||||
|
||||
OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
|
||||
OffscreenBuffer* buffer = mRenderState.layerPool().get(
|
||||
mRenderState, width, height, mWideColorGamut);
|
||||
startRepaintLayer(buffer, Rect(width, height));
|
||||
return buffer;
|
||||
}
|
||||
@@ -103,7 +104,8 @@ void BakedOpRenderer::endLayer() {
|
||||
OffscreenBuffer* BakedOpRenderer::copyToLayer(const Rect& area) {
|
||||
const uint32_t width = area.getWidth();
|
||||
const uint32_t height = area.getHeight();
|
||||
OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
|
||||
OffscreenBuffer* buffer = mRenderState.layerPool().get(
|
||||
mRenderState, width, height, mWideColorGamut);
|
||||
if (!area.isEmpty() && width != 0 && height != 0) {
|
||||
mCaches.textureState().activateTexture(0);
|
||||
mCaches.textureState().bindTexture(buffer->texture.id());
|
||||
|
||||
@@ -54,12 +54,13 @@ public:
|
||||
uint8_t spotShadowAlpha;
|
||||
};
|
||||
|
||||
BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque,
|
||||
BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut,
|
||||
const LightInfo& lightInfo)
|
||||
: mGlopReceiver(DefaultGlopReceiver)
|
||||
, mRenderState(renderState)
|
||||
, mCaches(caches)
|
||||
, mOpaque(opaque)
|
||||
, mWideColorGamut(wideColorGamut)
|
||||
, mLightInfo(lightInfo) {
|
||||
}
|
||||
|
||||
@@ -118,6 +119,7 @@ private:
|
||||
RenderState& mRenderState;
|
||||
Caches& mCaches;
|
||||
bool mOpaque;
|
||||
bool mWideColorGamut;
|
||||
bool mHasDrawn = false;
|
||||
|
||||
// render target state - setup by start/end layer/frame
|
||||
|
||||
@@ -120,6 +120,10 @@ void Texture::resetCachedParams() {
|
||||
void Texture::upload(GLint internalFormat, uint32_t width, uint32_t height,
|
||||
GLenum format, GLenum type, const void* pixels) {
|
||||
GL_CHECKPOINT(MODERATE);
|
||||
|
||||
// We don't have color space information, we assume the data is gamma encoded
|
||||
mIsLinear = false;
|
||||
|
||||
bool needsAlloc = updateLayout(width, height, internalFormat, format, GL_TEXTURE_2D);
|
||||
if (!mId) {
|
||||
glGenTextures(1, &mId);
|
||||
@@ -309,11 +313,16 @@ void Texture::upload(Bitmap& bitmap) {
|
||||
bool rgba16fNeedsConversion = bitmap.colorType() == kRGBA_F16_SkColorType
|
||||
&& internalFormat != GL_RGBA16F;
|
||||
|
||||
// RGBA16F is always linear extended sRGB
|
||||
if (internalFormat == GL_RGBA16F) {
|
||||
mIsLinear = true;
|
||||
}
|
||||
|
||||
mConnector.reset();
|
||||
|
||||
// RGBA16F is always extended sRGB, alpha masks don't have color profiles
|
||||
// Alpha masks don't have color profiles
|
||||
// If an RGBA16F bitmap needs conversion, we know the target will be sRGB
|
||||
if (internalFormat != GL_RGBA16F && internalFormat != GL_ALPHA && !rgba16fNeedsConversion) {
|
||||
if (!mIsLinear && internalFormat != GL_ALPHA && !rgba16fNeedsConversion) {
|
||||
SkColorSpace* colorSpace = bitmap.info().colorSpace();
|
||||
// If the bitmap is sRGB we don't need conversion
|
||||
if (colorSpace != nullptr && !colorSpace->isSRGB()) {
|
||||
|
||||
@@ -88,7 +88,8 @@ public:
|
||||
* The image data is undefined after calling this.
|
||||
*/
|
||||
void resize(uint32_t width, uint32_t height, GLint internalFormat, GLint format) {
|
||||
upload(internalFormat, width, height, format, GL_UNSIGNED_BYTE, nullptr);
|
||||
upload(internalFormat, width, height, format,
|
||||
internalFormat == GL_RGBA16F ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,7 +156,7 @@ public:
|
||||
* Returns true if this texture uses a linear encoding format.
|
||||
*/
|
||||
constexpr bool isLinear() const {
|
||||
return mInternalFormat == GL_RGBA16F;
|
||||
return mIsLinear;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,6 +220,9 @@ private:
|
||||
GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
|
||||
GLenum mMagFilter = GL_LINEAR;
|
||||
|
||||
// Indicates whether the content of the texture is in linear space
|
||||
bool mIsLinear = false;
|
||||
|
||||
Caches& mCaches;
|
||||
|
||||
std::unique_ptr<ColorSpaceConnector> mConnector;
|
||||
|
||||
@@ -61,7 +61,7 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty,
|
||||
const SkRect& dirty,
|
||||
const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue,
|
||||
const Rect& contentDrawBounds, bool opaque,
|
||||
const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo,
|
||||
const std::vector<sp<RenderNode>>& renderNodes,
|
||||
FrameInfoVisualizer* profiler) {
|
||||
@@ -85,7 +85,8 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty,
|
||||
mRenderThread.getGrContext(), renderTargetDesc, &props));
|
||||
|
||||
SkiaPipeline::updateLighting(lightGeometry, lightInfo);
|
||||
renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
|
||||
renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, wideColorGamut,
|
||||
contentDrawBounds, surface);
|
||||
layerUpdateQueue->clear();
|
||||
|
||||
// Draw visual debugging features
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
|
||||
const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue,
|
||||
const Rect& contentDrawBounds, bool opaque,
|
||||
const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo,
|
||||
const std::vector< sp<RenderNode> >& renderNodes,
|
||||
FrameInfoVisualizer* profiler) override;
|
||||
|
||||
@@ -72,16 +72,18 @@ void SkiaPipeline::unpinImages() {
|
||||
}
|
||||
|
||||
void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo) {
|
||||
updateLighting(lightGeometry, lightInfo);
|
||||
ATRACE_NAME("draw layers");
|
||||
renderVectorDrawableCache();
|
||||
renderLayersImpl(*layerUpdateQueue, opaque);
|
||||
renderLayersImpl(*layerUpdateQueue, opaque, wideColorGamut);
|
||||
layerUpdateQueue->clear();
|
||||
}
|
||||
|
||||
void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) {
|
||||
void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers,
|
||||
bool opaque, bool wideColorGamut) {
|
||||
// TODO: Handle wide color gamut
|
||||
// Render all layers that need to be updated, in order.
|
||||
for (size_t i = 0; i < layers.entries().size(); i++) {
|
||||
RenderNode* layerNode = layers.entries()[i].renderNode.get();
|
||||
@@ -129,12 +131,13 @@ void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque)
|
||||
}
|
||||
|
||||
bool SkiaPipeline::createOrUpdateLayer(RenderNode* node,
|
||||
const DamageAccumulator& damageAccumulator) {
|
||||
const DamageAccumulator& damageAccumulator, bool wideColorGamut) {
|
||||
SkSurface* layer = node->getLayerSurface();
|
||||
if (!layer || layer->width() != node->getWidth() || layer->height() != node->getHeight()) {
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(node->getWidth(), node->getHeight());
|
||||
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
|
||||
SkASSERT(mRenderThread.getGrContext() != nullptr);
|
||||
// TODO: Handle wide color gamut requests
|
||||
node->setLayerSurface(
|
||||
SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
|
||||
info, 0, &props));
|
||||
@@ -203,13 +206,13 @@ void SkiaPipeline::renderVectorDrawableCache() {
|
||||
}
|
||||
|
||||
void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
|
||||
const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
|
||||
sk_sp<SkSurface> surface) {
|
||||
const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut,
|
||||
const Rect &contentDrawBounds, sk_sp<SkSurface> surface) {
|
||||
|
||||
renderVectorDrawableCache();
|
||||
|
||||
// draw all layers up front
|
||||
renderLayersImpl(layers, opaque);
|
||||
renderLayersImpl(layers, opaque, wideColorGamut);
|
||||
|
||||
// initialize the canvas for the current frame
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
@@ -227,7 +230,7 @@ void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& cli
|
||||
}
|
||||
}
|
||||
|
||||
renderFrameImpl(layers, clip, nodes, opaque, contentDrawBounds, canvas);
|
||||
renderFrameImpl(layers, clip, nodes, opaque, wideColorGamut, contentDrawBounds, canvas);
|
||||
|
||||
if (skpCaptureEnabled() && recordingPicture) {
|
||||
sk_sp<SkPicture> picture = recorder->finishRecordingAsPicture();
|
||||
@@ -260,8 +263,8 @@ static Rect nodeBounds(RenderNode& node) {
|
||||
}
|
||||
|
||||
void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
|
||||
const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
|
||||
SkCanvas* canvas) {
|
||||
const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut,
|
||||
const Rect &contentDrawBounds, SkCanvas* canvas) {
|
||||
SkAutoCanvasRestore saver(canvas, true);
|
||||
canvas->androidFramework_setDeviceClipRestriction(clip.roundOut());
|
||||
|
||||
@@ -388,7 +391,7 @@ void SkiaPipeline::renderOverdraw(const LayerUpdateQueue& layers, const SkRect&
|
||||
// each time a pixel would have been drawn.
|
||||
// Pass true for opaque so we skip the clear - the overdrawCanvas is already zero
|
||||
// initialized.
|
||||
renderFrameImpl(layers, clip, nodes, true, contentDrawBounds, &overdrawCanvas);
|
||||
renderFrameImpl(layers, clip, nodes, true, false, contentDrawBounds, &overdrawCanvas);
|
||||
sk_sp<SkImage> counts = offscreen->makeImageSnapshot();
|
||||
|
||||
// Draw overdraw colors to the canvas. The color filter will convert counts to colors.
|
||||
|
||||
@@ -39,15 +39,15 @@ public:
|
||||
void unpinImages() override;
|
||||
|
||||
void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo) override;
|
||||
|
||||
bool createOrUpdateLayer(RenderNode* node,
|
||||
const DamageAccumulator& damageAccumulator) override;
|
||||
const DamageAccumulator& damageAccumulator, bool wideColorGamut) override;
|
||||
|
||||
void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
|
||||
const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
|
||||
sk_sp<SkSurface> surface);
|
||||
const std::vector< sp<RenderNode> >& nodes, bool opaque, bool wideColorGamut,
|
||||
const Rect &contentDrawBounds, sk_sp<SkSurface> surface);
|
||||
|
||||
std::vector<VectorDrawableRoot*>* getVectorDrawables() { return &mVectorDrawables; }
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
|
||||
|
||||
static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque);
|
||||
static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque, bool wideColorGamut);
|
||||
|
||||
static bool skpCaptureEnabled() { return false; }
|
||||
|
||||
@@ -110,8 +110,8 @@ protected:
|
||||
|
||||
private:
|
||||
void renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
|
||||
const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
|
||||
SkCanvas* canvas);
|
||||
const std::vector< sp<RenderNode> >& nodes, bool opaque, bool wideColorGamut,
|
||||
const Rect &contentDrawBounds, SkCanvas* canvas);
|
||||
|
||||
/**
|
||||
* Debugging feature. Draws a semi-transparent overlay on each pixel, indicating
|
||||
|
||||
@@ -66,7 +66,7 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty,
|
||||
const SkRect& dirty,
|
||||
const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue,
|
||||
const Rect& contentDrawBounds, bool opaque,
|
||||
const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo,
|
||||
const std::vector<sp<RenderNode>>& renderNodes,
|
||||
FrameInfoVisualizer* profiler) {
|
||||
@@ -76,7 +76,8 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty,
|
||||
return false;
|
||||
}
|
||||
SkiaPipeline::updateLighting(lightGeometry, lightInfo);
|
||||
renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer);
|
||||
renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, wideColorGamut,
|
||||
contentDrawBounds, backBuffer);
|
||||
layerUpdateQueue->clear();
|
||||
|
||||
// Draw visual debugging features
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
|
||||
const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue,
|
||||
const Rect& contentDrawBounds, bool opaque,
|
||||
const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo,
|
||||
const std::vector< sp<RenderNode> >& renderNodes,
|
||||
FrameInfoVisualizer* profiler) override;
|
||||
|
||||
@@ -35,17 +35,19 @@ namespace uirenderer {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches,
|
||||
uint32_t viewportWidth, uint32_t viewportHeight)
|
||||
uint32_t viewportWidth, uint32_t viewportHeight, bool wideColorGamut)
|
||||
: GpuMemoryTracker(GpuObjectType::OffscreenBuffer)
|
||||
, renderState(renderState)
|
||||
, viewportWidth(viewportWidth)
|
||||
, viewportHeight(viewportHeight)
|
||||
, texture(caches) {
|
||||
, texture(caches)
|
||||
, wideColorGamut(wideColorGamut) {
|
||||
uint32_t width = computeIdealDimension(viewportWidth);
|
||||
uint32_t height = computeIdealDimension(viewportHeight);
|
||||
ATRACE_FORMAT("Allocate %ux%u HW Layer", width, height);
|
||||
caches.textureState().activateTexture(0);
|
||||
texture.resize(width, height, caches.rgbaInternalFormat(), GL_RGBA);
|
||||
texture.resize(width, height,
|
||||
wideColorGamut ? GL_RGBA16F : caches.rgbaInternalFormat(), GL_RGBA);
|
||||
texture.blend = true;
|
||||
texture.setWrap(GL_CLAMP_TO_EDGE);
|
||||
// not setting filter on texture, since it's set when drawing, based on transform
|
||||
@@ -127,7 +129,10 @@ int OffscreenBufferPool::Entry::compare(const Entry& lhs, const Entry& rhs) {
|
||||
int deltaInt = int(lhs.width) - int(rhs.width);
|
||||
if (deltaInt != 0) return deltaInt;
|
||||
|
||||
return int(lhs.height) - int(rhs.height);
|
||||
deltaInt = int(lhs.height) - int(rhs.height);
|
||||
if (deltaInt != 0) return deltaInt;
|
||||
|
||||
return int(lhs.wideColorGamut) - int(rhs.wideColorGamut);
|
||||
}
|
||||
|
||||
void OffscreenBufferPool::clear() {
|
||||
@@ -139,10 +144,10 @@ void OffscreenBufferPool::clear() {
|
||||
}
|
||||
|
||||
OffscreenBuffer* OffscreenBufferPool::get(RenderState& renderState,
|
||||
const uint32_t width, const uint32_t height) {
|
||||
const uint32_t width, const uint32_t height, bool wideColorGamut) {
|
||||
OffscreenBuffer* layer = nullptr;
|
||||
|
||||
Entry entry(width, height);
|
||||
Entry entry(width, height, wideColorGamut);
|
||||
auto iter = mPool.find(entry);
|
||||
|
||||
if (iter != mPool.end()) {
|
||||
@@ -154,7 +159,8 @@ OffscreenBuffer* OffscreenBufferPool::get(RenderState& renderState,
|
||||
layer->viewportHeight = height;
|
||||
mSize -= layer->getSizeInBytes();
|
||||
} else {
|
||||
layer = new OffscreenBuffer(renderState, Caches::getInstance(), width, height);
|
||||
layer = new OffscreenBuffer(renderState, Caches::getInstance(),
|
||||
width, height, wideColorGamut);
|
||||
}
|
||||
|
||||
return layer;
|
||||
@@ -174,7 +180,7 @@ OffscreenBuffer* OffscreenBufferPool::resize(OffscreenBuffer* layer,
|
||||
return layer;
|
||||
}
|
||||
putOrDelete(layer);
|
||||
return get(renderState, width, height);
|
||||
return get(renderState, width, height, layer->wideColorGamut);
|
||||
}
|
||||
|
||||
void OffscreenBufferPool::dump() {
|
||||
|
||||
@@ -43,7 +43,7 @@ class RenderState;
|
||||
class OffscreenBuffer : GpuMemoryTracker {
|
||||
public:
|
||||
OffscreenBuffer(RenderState& renderState, Caches& caches,
|
||||
uint32_t viewportWidth, uint32_t viewportHeight);
|
||||
uint32_t viewportWidth, uint32_t viewportHeight, bool wideColorGamut = false);
|
||||
~OffscreenBuffer();
|
||||
|
||||
Rect getTextureCoordinates();
|
||||
@@ -68,6 +68,8 @@ public:
|
||||
uint32_t viewportHeight;
|
||||
Texture texture;
|
||||
|
||||
bool wideColorGamut = false;
|
||||
|
||||
// Portion of layer that has been drawn to. Used to minimize drawing area when
|
||||
// drawing back to screen / parent FBO.
|
||||
Region region;
|
||||
@@ -90,7 +92,7 @@ public:
|
||||
~OffscreenBufferPool();
|
||||
|
||||
WARN_UNUSED_RESULT OffscreenBuffer* get(RenderState& renderState,
|
||||
const uint32_t width, const uint32_t height);
|
||||
const uint32_t width, const uint32_t height, bool wideColorGamut = false);
|
||||
|
||||
WARN_UNUSED_RESULT OffscreenBuffer* resize(OffscreenBuffer* layer,
|
||||
const uint32_t width, const uint32_t height);
|
||||
@@ -122,14 +124,16 @@ private:
|
||||
struct Entry {
|
||||
Entry() {}
|
||||
|
||||
Entry(const uint32_t layerWidth, const uint32_t layerHeight)
|
||||
Entry(const uint32_t layerWidth, const uint32_t layerHeight, bool wideColorGamut)
|
||||
: width(OffscreenBuffer::computeIdealDimension(layerWidth))
|
||||
, height(OffscreenBuffer::computeIdealDimension(layerHeight)) {}
|
||||
, height(OffscreenBuffer::computeIdealDimension(layerHeight))
|
||||
, wideColorGamut(wideColorGamut) {}
|
||||
|
||||
explicit Entry(OffscreenBuffer* layer)
|
||||
: layer(layer)
|
||||
, width(layer->texture.width())
|
||||
, height(layer->texture.height()) {
|
||||
, height(layer->texture.height())
|
||||
, wideColorGamut(layer->wideColorGamut) {
|
||||
}
|
||||
|
||||
static int compare(const Entry& lhs, const Entry& rhs);
|
||||
@@ -149,6 +153,7 @@ private:
|
||||
OffscreenBuffer* layer = nullptr;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
bool wideColorGamut = false;
|
||||
}; // struct Entry
|
||||
|
||||
std::multiset<Entry> mPool;
|
||||
|
||||
@@ -421,7 +421,7 @@ void CanvasContext::draw() {
|
||||
SkRect windowDirty = computeDirtyRect(frame, &dirty);
|
||||
|
||||
bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
|
||||
mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes, &(profiler()));
|
||||
mContentDrawBounds, mOpaque, mWideColorGamut, mLightInfo, mRenderNodes, &(profiler()));
|
||||
|
||||
waitOnFences();
|
||||
|
||||
@@ -563,7 +563,8 @@ void CanvasContext::buildLayer(RenderNode* node) {
|
||||
// purposes when the frame is actually drawn
|
||||
node->setPropertyFieldsDirty(RenderNode::GENERIC);
|
||||
|
||||
mRenderPipeline->renderLayers(mLightGeometry, &mLayerUpdateQueue, mOpaque, mLightInfo);
|
||||
mRenderPipeline->renderLayers(mLightGeometry, &mLayerUpdateQueue,
|
||||
mOpaque, mWideColorGamut, mLightInfo);
|
||||
|
||||
node->incStrong(nullptr);
|
||||
mPrefetchedLayers.insert(node);
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
* @return true if the layer has been created or updated
|
||||
*/
|
||||
bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& dmgAccumulator) {
|
||||
return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator);
|
||||
return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator, mWideColorGamut);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
virtual bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
|
||||
const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue,
|
||||
const Rect& contentDrawBounds, bool opaque,
|
||||
const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo,
|
||||
const std::vector< sp<RenderNode> >& renderNodes,
|
||||
FrameInfoVisualizer* profiler) = 0;
|
||||
@@ -73,11 +73,11 @@ public:
|
||||
virtual bool isContextReady() = 0;
|
||||
virtual void onDestroyHardwareResources() = 0;
|
||||
virtual void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo) = 0;
|
||||
virtual TaskManager* getTaskManager() = 0;
|
||||
virtual bool createOrUpdateLayer(RenderNode* node,
|
||||
const DamageAccumulator& damageAccumulator) = 0;
|
||||
const DamageAccumulator& damageAccumulator, bool wideColorGamut) = 0;
|
||||
virtual bool pinImages(std::vector<SkImage*>& mutableImages) = 0;
|
||||
virtual bool pinImages(LsaVector<sk_sp<Bitmap>>& images) = 0;
|
||||
virtual void unpinImages() = 0;
|
||||
|
||||
@@ -58,7 +58,7 @@ Frame OpenGLPipeline::getFrame() {
|
||||
bool OpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
|
||||
const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue,
|
||||
const Rect& contentDrawBounds, bool opaque,
|
||||
const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo,
|
||||
const std::vector< sp<RenderNode> >& renderNodes,
|
||||
FrameInfoVisualizer* profiler) {
|
||||
@@ -77,7 +77,7 @@ bool OpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const S
|
||||
frameBuilder.deferRenderNodeScene(renderNodes, contentDrawBounds);
|
||||
|
||||
BakedOpRenderer renderer(caches, mRenderThread.renderState(),
|
||||
opaque, lightInfo);
|
||||
opaque, wideColorGamut, lightInfo);
|
||||
frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
|
||||
ProfileRenderer profileRenderer(renderer);
|
||||
profiler->draw(profileRenderer);
|
||||
@@ -184,14 +184,14 @@ void OpenGLPipeline::onDestroyHardwareResources() {
|
||||
}
|
||||
|
||||
void OpenGLPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo) {
|
||||
static const std::vector< sp<RenderNode> > emptyNodeList;
|
||||
auto& caches = Caches::getInstance();
|
||||
FrameBuilder frameBuilder(*layerUpdateQueue, lightGeometry, caches);
|
||||
layerUpdateQueue->clear();
|
||||
BakedOpRenderer renderer(caches, mRenderThread.renderState(),
|
||||
opaque, lightInfo);
|
||||
// TODO: Handle wide color gamut contexts
|
||||
BakedOpRenderer renderer(caches, mRenderThread.renderState(), opaque, wideColorGamut, lightInfo);
|
||||
LOG_ALWAYS_FATAL_IF(renderer.didDraw(), "shouldn't draw in buildlayer case");
|
||||
frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
|
||||
}
|
||||
@@ -205,12 +205,13 @@ static bool layerMatchesWH(OffscreenBuffer* layer, int width, int height) {
|
||||
}
|
||||
|
||||
bool OpenGLPipeline::createOrUpdateLayer(RenderNode* node,
|
||||
const DamageAccumulator& damageAccumulator) {
|
||||
const DamageAccumulator& damageAccumulator, bool wideColorGamut) {
|
||||
RenderState& renderState = mRenderThread.renderState();
|
||||
OffscreenBufferPool& layerPool = renderState.layerPool();
|
||||
bool transformUpdateNeeded = false;
|
||||
if (node->getLayer() == nullptr) {
|
||||
node->setLayer(layerPool.get(renderState, node->getWidth(), node->getHeight()));
|
||||
node->setLayer(layerPool.get(renderState,
|
||||
node->getWidth(), node->getHeight(), wideColorGamut));
|
||||
transformUpdateNeeded = true;
|
||||
} else if (!layerMatchesWH(node->getLayer(), node->getWidth(), node->getHeight())) {
|
||||
// TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering)
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
|
||||
const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue,
|
||||
const Rect& contentDrawBounds, bool opaque,
|
||||
const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo,
|
||||
const std::vector< sp<RenderNode> >& renderNodes,
|
||||
FrameInfoVisualizer* profiler) override;
|
||||
@@ -50,11 +50,11 @@ public:
|
||||
bool isContextReady() override;
|
||||
void onDestroyHardwareResources() override;
|
||||
void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque,
|
||||
LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
|
||||
const BakedOpRenderer::LightInfo& lightInfo) override;
|
||||
TaskManager* getTaskManager() override;
|
||||
bool createOrUpdateLayer(RenderNode* node,
|
||||
const DamageAccumulator& damageAccumulator) override;
|
||||
const DamageAccumulator& damageAccumulator, bool wideColorGamut) override;
|
||||
bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
|
||||
bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override;
|
||||
void unpinImages() override;
|
||||
|
||||
@@ -83,7 +83,7 @@ void BM_FrameBuilder_deferAndRender(benchmark::State& state) {
|
||||
sLightGeometry, caches);
|
||||
frameBuilder.deferRenderNode(*node);
|
||||
|
||||
BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
|
||||
BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
|
||||
frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
|
||||
benchmark::DoNotOptimize(&renderer);
|
||||
}
|
||||
@@ -142,7 +142,7 @@ void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) {
|
||||
sLightGeometry, Caches::getInstance());
|
||||
frameBuilder.deferRenderNode(*node);
|
||||
|
||||
BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
|
||||
BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
|
||||
frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
|
||||
benchmark::DoNotOptimize(&renderer);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ const FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50};
|
||||
class ValidatingBakedOpRenderer : public BakedOpRenderer {
|
||||
public:
|
||||
ValidatingBakedOpRenderer(RenderState& renderState, std::function<void(const Glop& glop)> validator)
|
||||
: BakedOpRenderer(Caches::getInstance(), renderState, true, sLightInfo)
|
||||
: BakedOpRenderer(Caches::getInstance(), renderState, true, false, sLightInfo)
|
||||
, mValidator(validator) {
|
||||
mGlopReceiver = ValidatingGlopReceiver;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ using namespace android::uirenderer;
|
||||
const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 };
|
||||
|
||||
RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpRenderer, startRepaintLayer_clear) {
|
||||
BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(), true, sLightInfo);
|
||||
BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(),
|
||||
true, false, sLightInfo);
|
||||
OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200u, 200u);
|
||||
|
||||
layer.dirty(Rect(200, 200));
|
||||
|
||||
@@ -45,7 +45,7 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(LeakCheck, saveLayer_overdrawRejection) {
|
||||
FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100,
|
||||
sLightGeometery, Caches::getInstance());
|
||||
frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
|
||||
BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
|
||||
BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
|
||||
frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,6 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(LeakCheck, saveLayerUnclipped_simple) {
|
||||
FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200,
|
||||
sLightGeometery, Caches::getInstance());
|
||||
frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
|
||||
BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
|
||||
BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
|
||||
frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,19 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, construct) {
|
||||
EXPECT_EQ(64u * 192u * 4u, layer.getSizeInBytes());
|
||||
}
|
||||
|
||||
RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, constructWideColorGamut) {
|
||||
OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 49u, 149u, true);
|
||||
EXPECT_EQ(49u, layer.viewportWidth);
|
||||
EXPECT_EQ(149u, layer.viewportHeight);
|
||||
|
||||
EXPECT_EQ(64u, layer.texture.width());
|
||||
EXPECT_EQ(192u, layer.texture.height());
|
||||
|
||||
EXPECT_TRUE(layer.wideColorGamut);
|
||||
|
||||
EXPECT_EQ(64u * 192u * 8u, layer.getSizeInBytes());
|
||||
}
|
||||
|
||||
RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, getTextureCoordinates) {
|
||||
OffscreenBuffer layerAligned(renderThread.renderState(), Caches::getInstance(), 256u, 256u);
|
||||
EXPECT_EQ(Rect(0, 1, 1, 0),
|
||||
@@ -88,6 +101,47 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClear) {
|
||||
EXPECT_EQ(0u, pool.getCount());
|
||||
}
|
||||
|
||||
RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClearWideColorGamut) {
|
||||
OffscreenBufferPool pool;
|
||||
|
||||
auto layer = pool.get(renderThread.renderState(), 100u, 200u, true);
|
||||
EXPECT_EQ(100u, layer->viewportWidth);
|
||||
EXPECT_EQ(200u, layer->viewportHeight);
|
||||
EXPECT_TRUE(layer->wideColorGamut);
|
||||
|
||||
ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize());
|
||||
|
||||
pool.putOrDelete(layer);
|
||||
ASSERT_EQ(layer->getSizeInBytes(), pool.getSize());
|
||||
|
||||
auto layer2 = pool.get(renderThread.renderState(), 102u, 202u, true);
|
||||
EXPECT_EQ(layer, layer2) << "layer should be recycled";
|
||||
ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer";
|
||||
|
||||
pool.putOrDelete(layer2);
|
||||
EXPECT_EQ(1u, pool.getCount());
|
||||
pool.clear();
|
||||
EXPECT_EQ(0u, pool.getSize());
|
||||
EXPECT_EQ(0u, pool.getCount());
|
||||
|
||||
// add non wide gamut layer
|
||||
auto layer3 = pool.get(renderThread.renderState(), 100u, 200u);
|
||||
EXPECT_FALSE(layer3->wideColorGamut);
|
||||
pool.putOrDelete(layer3);
|
||||
EXPECT_EQ(1u, pool.getCount());
|
||||
|
||||
auto layer4 = pool.get(renderThread.renderState(), 100u, 200u, true);
|
||||
EXPECT_TRUE(layer4->wideColorGamut);
|
||||
EXPECT_EQ(1u, pool.getCount());
|
||||
ASSERT_NE(layer3, layer4);
|
||||
|
||||
pool.putOrDelete(layer4);
|
||||
|
||||
pool.clear();
|
||||
EXPECT_EQ(0u, pool.getSize());
|
||||
EXPECT_EQ(0u, pool.getCount());
|
||||
}
|
||||
|
||||
RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resize) {
|
||||
OffscreenBufferPool pool;
|
||||
|
||||
@@ -123,6 +177,43 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resize) {
|
||||
pool.putOrDelete(layer2);
|
||||
}
|
||||
|
||||
RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resizeWideColorGamut) {
|
||||
OffscreenBufferPool pool;
|
||||
|
||||
auto layer = pool.get(renderThread.renderState(), 64u, 64u, true);
|
||||
|
||||
// resize in place
|
||||
ASSERT_EQ(layer, pool.resize(layer, 60u, 55u));
|
||||
EXPECT_EQ(60u, layer->viewportWidth);
|
||||
EXPECT_EQ(55u, layer->viewportHeight);
|
||||
EXPECT_EQ(64u, layer->texture.width());
|
||||
EXPECT_EQ(64u, layer->texture.height());
|
||||
|
||||
EXPECT_TRUE(layer->wideColorGamut);
|
||||
EXPECT_EQ(64u * 64u * 8u, layer->getSizeInBytes());
|
||||
|
||||
// resized to use different object in pool
|
||||
auto layer2 = pool.get(renderThread.renderState(), 128u, 128u, true);
|
||||
pool.putOrDelete(layer2);
|
||||
ASSERT_EQ(1u, pool.getCount());
|
||||
|
||||
// add a non-wide gamut layer
|
||||
auto layer3 = pool.get(renderThread.renderState(), 128u, 128u);
|
||||
pool.putOrDelete(layer3);
|
||||
ASSERT_EQ(2u, pool.getCount());
|
||||
|
||||
ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u));
|
||||
EXPECT_EQ(120u, layer2->viewportWidth);
|
||||
EXPECT_EQ(125u, layer2->viewportHeight);
|
||||
EXPECT_EQ(128u, layer2->texture.width());
|
||||
EXPECT_EQ(128u, layer2->texture.height());
|
||||
|
||||
EXPECT_TRUE(layer2->wideColorGamut);
|
||||
EXPECT_EQ(128u * 128u * 8u, layer2->getSizeInBytes());
|
||||
|
||||
pool.putOrDelete(layer2);
|
||||
}
|
||||
|
||||
RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, putAndDestroy) {
|
||||
OffscreenBufferPool pool;
|
||||
// layer too big to return to the pool
|
||||
@@ -153,3 +244,4 @@ RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, clear) {
|
||||
|
||||
EXPECT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer));
|
||||
}
|
||||
|
||||
|
||||
@@ -450,7 +450,7 @@ RENDERTHREAD_TEST(RenderNodeDrawable, projectionHwLayer) {
|
||||
LayerUpdateQueue layerUpdateQueue;
|
||||
layerUpdateQueue.enqueueLayerWithDamage(child.get(),
|
||||
android::uirenderer::Rect(LAYER_WIDTH, LAYER_HEIGHT));
|
||||
SkiaPipeline::renderLayersImpl(layerUpdateQueue, true);
|
||||
SkiaPipeline::renderLayersImpl(layerUpdateQueue, true, false);
|
||||
EXPECT_EQ(1, drawCounter); //assert index 0 is drawn on the layer
|
||||
|
||||
RenderNodeDrawable drawable(parent.get(), surfaceLayer1->getCanvas(), true);
|
||||
|
||||
@@ -51,7 +51,8 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) {
|
||||
auto surface = SkSurface::MakeRasterN32Premul(1, 1);
|
||||
surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
|
||||
opaque, false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
|
||||
}
|
||||
|
||||
@@ -72,10 +73,12 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) {
|
||||
auto surface = SkSurface::MakeRasterN32Premul(2, 2);
|
||||
surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
|
||||
true, false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, false, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
|
||||
false, false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned int)SK_ColorTRANSPARENT);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
|
||||
}
|
||||
@@ -94,7 +97,8 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckDirtyRect) {
|
||||
auto surface = SkSurface::MakeRasterN32Premul(2, 2);
|
||||
surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
|
||||
true, false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 1, 0), SK_ColorBLUE);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorRED);
|
||||
@@ -135,7 +139,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderLayer) {
|
||||
lightGeometry.center = { 0.0f, 0.0f, 0.0f };
|
||||
BakedOpRenderer::LightInfo lightInfo;
|
||||
auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
|
||||
pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, lightInfo);
|
||||
pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, false, lightInfo);
|
||||
ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED);
|
||||
ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorBLUE);
|
||||
ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 1), SK_ColorWHITE);
|
||||
@@ -166,32 +170,38 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderOverdraw) {
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
|
||||
|
||||
// Single draw, should be white.
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
|
||||
false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
|
||||
|
||||
// 1 Overdraw, should be blue blended onto white.
|
||||
renderNodes.push_back(whiteNode);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
|
||||
false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffd0d0ff);
|
||||
|
||||
// 2 Overdraw, should be green blended onto white
|
||||
renderNodes.push_back(whiteNode);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
|
||||
false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffd0ffd0);
|
||||
|
||||
// 3 Overdraw, should be pink blended onto white.
|
||||
renderNodes.push_back(whiteNode);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
|
||||
false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffffc0c0);
|
||||
|
||||
// 4 Overdraw, should be red blended onto white.
|
||||
renderNodes.push_back(whiteNode);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
|
||||
false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffff8080);
|
||||
|
||||
// 5 Overdraw, should be red blended onto white.
|
||||
renderNodes.push_back(whiteNode);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
|
||||
false, contentDrawBounds, surface);
|
||||
ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffff8080);
|
||||
}
|
||||
|
||||
@@ -278,7 +288,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, deferRenderNodeScene) {
|
||||
SkRect dirty = SkRect::MakeWH(800, 600);
|
||||
auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
|
||||
sk_sp<DeferLayer<DeferTestCanvas>> surface(new DeferLayer<DeferTestCanvas>());
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, contentDrawBounds, surface);
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false, contentDrawBounds, surface);
|
||||
EXPECT_EQ(4, surface->canvas()->mDrawCounter);
|
||||
}
|
||||
|
||||
@@ -308,7 +318,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped) {
|
||||
SkRect dirty = SkRect::MakeLTRB(10, 20, 30, 40);
|
||||
auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
|
||||
sk_sp<DeferLayer<ClippedTestCanvas>> surface(new DeferLayer<ClippedTestCanvas>());
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false,
|
||||
SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
|
||||
EXPECT_EQ(1, surface->canvas()->mDrawCounter);
|
||||
}
|
||||
@@ -339,7 +349,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) {
|
||||
SkRect dirty = SkRect::MakeLTRB(10, 10, 40, 40);
|
||||
auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
|
||||
sk_sp<DeferLayer<ClipReplaceTestCanvas>> surface(new DeferLayer<ClipReplaceTestCanvas>());
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
|
||||
pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false,
|
||||
SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
|
||||
EXPECT_EQ(1, surface->canvas()->mDrawCounter);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user