summaryrefslogtreecommitdiffstats
path: root/libs/hwui/Layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/Layer.cpp')
-rw-r--r--libs/hwui/Layer.cpp101
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