Finish shadow support in new reorderer/renderer
Now passes alphas and light radius, and correctly transforms light
center for layers.
Also fixes begin-frame/layer clears to be damage rect aware.
Change-Id: I3b1415cd7bf1518c510145ebebdb745f494a2542
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index 1aa291f..d2d3285 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -35,11 +35,11 @@
LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
- startRepaintLayer(buffer);
+ startRepaintLayer(buffer, Rect(width, height));
return buffer;
}
-void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer) {
+void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) {
LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
mRenderTarget.offscreenBuffer = offscreenBuffer;
@@ -55,12 +55,10 @@
LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
"framebuffer incomplete!");
- // Clear the FBO
- mRenderState.scissor().setEnabled(false);
- glClear(GL_COLOR_BUFFER_BIT);
-
// Change the viewport & ortho projection
setViewport(offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight);
+
+ clearColorBuffer(repaintRect);
}
void BakedOpRenderer::endLayer() {
@@ -74,16 +72,13 @@
mRenderTarget.frameBufferId = -1;
}
-void BakedOpRenderer::startFrame(uint32_t width, uint32_t height) {
+void BakedOpRenderer::startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) {
mRenderState.bindFramebuffer(0);
setViewport(width, height);
mCaches.clearGarbage();
if (!mOpaque) {
- // TODO: partial invalidate!
- mRenderState.scissor().setEnabled(false);
- glClear(GL_COLOR_BUFFER_BIT);
- mHasDrawn = true;
+ clearColorBuffer(repaintRect);
}
}
@@ -113,6 +108,20 @@
mRenderState.blend().syncEnabled();
}
+void BakedOpRenderer::clearColorBuffer(const Rect& rect) {
+ if (Rect(mRenderTarget.viewportWidth, mRenderTarget.viewportHeight).contains(rect)) {
+ // Full viewport is being cleared - disable scissor
+ mRenderState.scissor().setEnabled(false);
+ } else {
+ // Requested rect is subset of viewport - scissor to it to avoid over-clearing
+ mRenderState.scissor().setEnabled(true);
+ mRenderState.scissor().set(rect.left, mRenderTarget.viewportHeight - rect.bottom,
+ rect.getWidth(), rect.getHeight());
+ }
+ glClear(GL_COLOR_BUFFER_BIT);
+ if (!mRenderTarget.frameBufferId) mHasDrawn = true;
+}
+
Texture* BakedOpRenderer::getTexture(const SkBitmap* bitmap) {
Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
if (!texture) {
@@ -136,7 +145,7 @@
mRenderTarget.offscreenBuffer->region.orSelf(dirty);
}
mRenderState.render(glop, mRenderTarget.orthoMatrix);
- mHasDrawn = true;
+ if (!mRenderTarget.frameBufferId) mHasDrawn = true;
}
////////////////////////////////////////////////////////////////////////////////
@@ -217,7 +226,7 @@
paint.setAntiAlias(true); // want to use AlphaVertex
// The caller has made sure casterAlpha > 0.
- uint8_t ambientShadowAlpha = 128u; //TODO: mAmbientShadowAlpha;
+ uint8_t ambientShadowAlpha = renderer.getLightInfo().ambientShadowAlpha;
if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
ambientShadowAlpha = Properties::overrideAmbientShadowStrength;
}
@@ -227,7 +236,7 @@
paint, VertexBufferRenderFlags::ShadowInterp);
}
- uint8_t spotShadowAlpha = 128u; //TODO: mSpotShadowAlpha;
+ uint8_t spotShadowAlpha = renderer.getLightInfo().spotShadowAlpha;
if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
spotShadowAlpha = Properties::overrideSpotShadowStrength;
}
@@ -240,12 +249,10 @@
void BakedOpDispatcher::onShadowOp(BakedOpRenderer& renderer, const ShadowOp& op, const BakedOpState& state) {
TessellationCache::vertexBuffer_pair_t buffers;
- Vector3 lightCenter = { 300, 300, 300 }; // TODO!
- float lightRadius = 150; // TODO!
-
renderer.caches().tessellationCache.getShadowBuffers(&state.computedState.transform,
op.localClipRect, op.casterAlpha >= 1.0f, op.casterPath,
- &op.shadowMatrixXY, &op.shadowMatrixZ, lightCenter, lightRadius,
+ &op.shadowMatrixXY, &op.shadowMatrixZ,
+ op.lightCenter, renderer.getLightInfo().lightRadius,
buffers);
renderShadow(renderer, state, op.casterAlpha, buffers.first, buffers.second);