diff options
Diffstat (limited to 'libs/hwui/Layer.cpp')
| -rw-r--r-- | libs/hwui/Layer.cpp | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 987bf03..8639ae1 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -18,18 +18,21 @@ #include <utils/Log.h> -#include "DisplayList.h" +#include "Caches.h" #include "DeferredDisplayList.h" +#include "RenderState.h" #include "Layer.h" #include "LayerRenderer.h" #include "OpenGLRenderer.h" -#include "Caches.h" +#include "RenderNode.h" namespace android { namespace uirenderer { -Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight): - caches(Caches::getInstance()), texture(caches) { +Layer::Layer(RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight) + : caches(Caches::getInstance()) + , renderState(renderState) + , texture(caches) { mesh = NULL; meshElementCount = 0; cacheable = true; @@ -41,22 +44,26 @@ Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight): colorFilter = NULL; deferredUpdateScheduled = false; renderer = NULL; - displayList = NULL; + renderNode = NULL; fbo = 0; stencil = NULL; debugDrawUpdate = false; hasDrawnSinceUpdate = false; + forceFilter = false; deferredList = NULL; + convexMask = NULL; caches.resourceCache.incrementRefcount(this); + rendererLightPosDirty = true; } Layer::~Layer() { - if (colorFilter) caches.resourceCache.decrementRefcount(colorFilter); + SkSafeUnref(colorFilter); removeFbo(); deleteTexture(); delete[] mesh; delete deferredList; + delete renderer; } uint32_t Layer::computeIdealWidth(uint32_t layerWidth) { @@ -67,6 +74,24 @@ uint32_t Layer::computeIdealHeight(uint32_t layerHeight) { return uint32_t(ceilf(layerHeight / float(LAYER_SIZE)) * LAYER_SIZE); } +void Layer::requireRenderer() { + if (!renderer) { + renderer = new LayerRenderer(renderState, this); + renderer->initProperties(); + } +} + +void Layer::updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer) { + if (renderer && rendererLightPosDirty) { + // re-init renderer's light position, based upon last cached location in window + Vector3 lightPos = rootRenderer.getLightCenter(); + cachedInvTransformInWindow.mapPoint3d(lightPos); + renderer->initLight(lightPos, rootRenderer.getLightRadius(), + rootRenderer.getAmbientShadowAlpha(), rootRenderer.getSpotShadowAlpha()); + rendererLightPosDirty = false; + } +} + bool Layer::resize(const uint32_t width, const uint32_t height) { uint32_t desiredWidth = computeIdealWidth(width); uint32_t desiredHeight = computeIdealWidth(height); @@ -75,6 +100,8 @@ bool Layer::resize(const uint32_t width, const uint32_t height) { return true; } + ATRACE_NAME("resizeLayer"); + const uint32_t maxTextureSize = caches.maxTextureSize; if (desiredWidth > maxTextureSize || desiredHeight > maxTextureSize) { ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)", @@ -113,36 +140,38 @@ bool Layer::resize(const uint32_t width, const uint32_t height) { void Layer::removeFbo(bool flush) { if (stencil) { - GLuint previousFbo; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); - if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo); + GLuint previousFbo = renderState.getFramebuffer(); + renderState.bindFramebuffer(fbo); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); - if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); + renderState.bindFramebuffer(previousFbo); caches.renderBufferCache.put(stencil); stencil = NULL; } if (fbo) { - if (flush) LayerRenderer::flushLayer(this); + if (flush) LayerRenderer::flushLayer(renderState, this); // If put fails the cache will delete the FBO caches.fboCache.put(fbo); fbo = 0; } } -void Layer::setPaint(SkPaint* paint) { +void Layer::updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom) { + requireRenderer(); + this->renderNode = renderNode; + const Rect r(left, top, right, bottom); + dirtyRect.unionWith(r); + deferredUpdateScheduled = true; +} + +void Layer::setPaint(const SkPaint* paint) { OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode); + setColorFilter((paint) ? paint->getColorFilter() : NULL); } -void Layer::setColorFilter(SkiaColorFilter* filter) { - if (colorFilter) { - caches.resourceCache.decrementRefcount(colorFilter); - } - colorFilter = filter; - if (colorFilter) { - caches.resourceCache.incrementRefcount(colorFilter); - } +void Layer::setColorFilter(SkColorFilter* filter) { + SkRefCnt_SafeAssign(colorFilter, filter); } void Layer::bindTexture() const { @@ -186,7 +215,8 @@ void Layer::allocateTexture() { } } -void Layer::defer() { +void Layer::defer(const OpenGLRenderer& rootRenderer) { + updateLightPosFromRenderer(rootRenderer); const float width = layer.getWidth(); const float height = layer.getHeight(); @@ -195,26 +225,24 @@ void Layer::defer() { dirtyRect.set(0, 0, width, height); } - if (deferredList) { - deferredList->reset(dirtyRect); - } else { - deferredList = new DeferredDisplayList(dirtyRect); - } + delete deferredList; + deferredList = new DeferredDisplayList(dirtyRect); + DeferStateStruct deferredState(*deferredList, *renderer, - DisplayList::kReplayFlag_ClipChildren); + RenderNode::kReplayFlag_ClipChildren); - renderer->initViewport(width, height); + renderer->setViewport(width, height); renderer->setupFrameState(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend()); - displayList->defer(deferredState, 0); + renderNode->computeOrdering(); + renderNode->defer(deferredState, 0); deferredUpdateScheduled = false; } void Layer::cancelDefer() { - renderer = NULL; - displayList = NULL; + renderNode = NULL; deferredUpdateScheduled = false; if (deferredList) { delete deferredList; @@ -232,27 +260,26 @@ void Layer::flush() { deferredList->flush(*renderer, dirtyRect); renderer->finish(); - renderer = NULL; dirtyRect.setEmpty(); - displayList = NULL; + renderNode = NULL; } } -void Layer::render() { +void Layer::render(const OpenGLRenderer& rootRenderer) { + updateLightPosFromRenderer(rootRenderer); renderer->setViewport(layer.getWidth(), layer.getHeight()); renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend()); - renderer->drawDisplayList(displayList, dirtyRect, DisplayList::kReplayFlag_ClipChildren); + renderer->drawRenderNode(renderNode.get(), dirtyRect, RenderNode::kReplayFlag_ClipChildren); renderer->finish(); - renderer = NULL; dirtyRect.setEmpty(); deferredUpdateScheduled = false; - displayList = NULL; + renderNode = NULL; } }; // namespace uirenderer |
