diff options
Diffstat (limited to 'libs/hwui/Layer.cpp')
| -rw-r--r-- | libs/hwui/Layer.cpp | 86 |
1 files changed, 69 insertions, 17 deletions
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 4adad05..bd371a3 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -28,9 +28,9 @@ namespace android { namespace uirenderer { -Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight) { +Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight): + caches(Caches::getInstance()), texture(caches) { mesh = NULL; - meshIndices = NULL; meshElementCount = 0; cacheable = true; dirty = false; @@ -47,16 +47,15 @@ Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight) { debugDrawUpdate = false; hasDrawnSinceUpdate = false; deferredList = NULL; - Caches::getInstance().resourceCache.incrementRefcount(this); + caches.resourceCache.incrementRefcount(this); } Layer::~Layer() { - if (colorFilter) Caches::getInstance().resourceCache.decrementRefcount(colorFilter); + if (colorFilter) caches.resourceCache.decrementRefcount(colorFilter); removeFbo(); deleteTexture(); delete[] mesh; - delete[] meshIndices; delete deferredList; } @@ -76,7 +75,7 @@ bool Layer::resize(const uint32_t width, const uint32_t height) { return true; } - const uint32_t maxTextureSize = Caches::getInstance().maxTextureSize; + 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)", desiredWidth, desiredHeight, maxTextureSize, maxTextureSize); @@ -89,7 +88,7 @@ bool Layer::resize(const uint32_t width, const uint32_t height) { setSize(desiredWidth, desiredHeight); if (fbo) { - Caches::getInstance().activeTexture(0); + caches.activeTexture(0); bindTexture(); allocateTexture(); @@ -120,14 +119,14 @@ void Layer::removeFbo(bool flush) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); - Caches::getInstance().renderBufferCache.put(stencil); + caches.renderBufferCache.put(stencil); stencil = NULL; } if (fbo) { if (flush) LayerRenderer::flushLayer(this); // If put fails the cache will delete the FBO - Caches::getInstance().fboCache.put(fbo); + caches.fboCache.put(fbo); fbo = 0; } } @@ -138,21 +137,55 @@ void Layer::setPaint(SkPaint* paint) { void Layer::setColorFilter(SkiaColorFilter* filter) { if (colorFilter) { - Caches::getInstance().resourceCache.decrementRefcount(colorFilter); + caches.resourceCache.decrementRefcount(colorFilter); } colorFilter = filter; if (colorFilter) { - Caches::getInstance().resourceCache.incrementRefcount(colorFilter); + caches.resourceCache.incrementRefcount(colorFilter); } } -void Layer::defer() { - if (!deferredList) { - deferredList = new DeferredDisplayList; +void Layer::bindTexture() const { + if (texture.id) { + caches.bindTexture(renderTarget, texture.id); } - DeferStateStruct deferredState(*deferredList, *renderer, - DisplayList::kReplayFlag_ClipChildren); +} + +void Layer::bindStencilRenderBuffer() const { + if (stencil) { + stencil->bind(); + } +} + +void Layer::generateTexture() { + if (!texture.id) { + glGenTextures(1, &texture.id); + } +} + +void Layer::deleteTexture() { + if (texture.id) { + texture.deleteTexture(); + texture.id = 0; + } +} + +void Layer::clearTexture() { + texture.id = 0; +} +void Layer::allocateTexture() { +#if DEBUG_LAYERS + ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight()); +#endif + if (texture.id) { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } +} + +void Layer::defer() { const float width = layer.getWidth(); const float height = layer.getHeight(); @@ -161,6 +194,14 @@ void Layer::defer() { dirtyRect.set(0, 0, width, height); } + if (deferredList) { + deferredList->reset(dirtyRect); + } else { + deferredList = new DeferredDisplayList(dirtyRect); + } + DeferStateStruct deferredState(*deferredList, *renderer, + DisplayList::kReplayFlag_ClipChildren); + renderer->initViewport(width, height); renderer->setupFrameState(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend()); @@ -170,8 +211,19 @@ void Layer::defer() { deferredUpdateScheduled = false; } -void Layer::flush() { +void Layer::cancelDefer() { + renderer = NULL; + displayList = NULL; + deferredUpdateScheduled = false; if (deferredList) { + delete deferredList; + deferredList = NULL; + } +} + +void Layer::flush() { + // renderer is checked as layer may be destroyed/put in layer cache with flush scheduled + if (deferredList && renderer) { renderer->setViewport(layer.getWidth(), layer.getHeight()); renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend()); |
