diff options
author | 2014-08-14 13:34:01 -0700 | |
---|---|---|
committer | 2014-08-15 00:59:44 +0000 | |
commit | 69e5adffb19135d51bde8e458f4907d7265f3e23 (patch) | |
tree | 022fc23512ae5adfbe3f86351305bc9f4538a68a | |
parent | e222e359a0aab985488a711f6edb76820fe8c6df (diff) |
Define shadow casting behavior within layers
bug:15860114
Savelayers and HW layers both now support shadow casting.
For save layers, the light source should always be correct, for HW
layers, the light source position is set when the layer is created,
and updated when it is resized.
Change-Id: Ie85567dd43c2bb0a0b08fd0bd4db41efa793ac2b
-rw-r--r-- | libs/hwui/Animator.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/DamageAccumulator.cpp | 32 | ||||
-rw-r--r-- | libs/hwui/DamageAccumulator.h | 43 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 18 | ||||
-rw-r--r-- | libs/hwui/Layer.h | 16 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.cpp | 7 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.h | 4 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 13 | ||||
-rw-r--r-- | libs/hwui/RenderNode.h | 4 | ||||
-rw-r--r-- | libs/hwui/Snapshot.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/Snapshot.h | 4 | ||||
-rw-r--r-- | libs/hwui/StatefulBaseRenderer.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/StatefulBaseRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/TessellationCache.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/TreeInfo.h | 7 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.cpp | 2 |
19 files changed, 104 insertions, 73 deletions
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp index 5ecd77ae53b0..78d569dfad2e 100644 --- a/libs/hwui/Animator.cpp +++ b/libs/hwui/Animator.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "RT-Animator" - #include "Animator.h" #include <inttypes.h> diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp index 15bed585cccf..054a1640c59c 100644 --- a/libs/hwui/DamageAccumulator.cpp +++ b/libs/hwui/DamageAccumulator.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "DamageAccumulator" - #include "DamageAccumulator.h" #include <cutils/log.h> @@ -26,12 +24,6 @@ namespace android { namespace uirenderer { -NullDamageAccumulator NullDamageAccumulator::sInstance; - -NullDamageAccumulator* NullDamageAccumulator::instance() { - return &sInstance; -} - enum TransformType { TransformInvalid = 0, TransformRenderNode, @@ -60,6 +52,30 @@ DamageAccumulator::DamageAccumulator() { mHead->type = TransformNone; } +static void computeTransformImpl(const DirtyStack* currentFrame, Matrix4* outMatrix) { + if (currentFrame->prev != currentFrame) { + computeTransformImpl(currentFrame->prev, outMatrix); + } + switch (currentFrame->type) { + case TransformRenderNode: + currentFrame->renderNode->applyViewPropertyTransforms(*outMatrix); + break; + case TransformMatrix4: + outMatrix->multiply(*currentFrame->matrix4); + break; + case TransformNone: + // nothing to be done + break; + default: + LOG_ALWAYS_FATAL("Tried to compute transform with an invalid type: %d", currentFrame->type); + } +} + +void DamageAccumulator::computeCurrentTransform(Matrix4* outMatrix) const { + outMatrix->loadIdentity(); + computeTransformImpl(mHead, outMatrix); +} + void DamageAccumulator::pushCommon() { if (!mHead->next) { DirtyStack* nextFrame = (DirtyStack*) mAllocator.alloc(sizeof(DirtyStack)); diff --git a/libs/hwui/DamageAccumulator.h b/libs/hwui/DamageAccumulator.h index 90d942515509..6f0bd8c187cc 100644 --- a/libs/hwui/DamageAccumulator.h +++ b/libs/hwui/DamageAccumulator.h @@ -31,18 +31,7 @@ struct DirtyStack; class RenderNode; class Matrix4; -class IDamageAccumulator { -public: - virtual void pushTransform(const RenderNode* transform) = 0; - virtual void pushTransform(const Matrix4* transform) = 0; - virtual void popTransform() = 0; - virtual void dirty(float left, float top, float right, float bottom) = 0; - virtual void peekAtDirty(SkRect* dest) = 0; -protected: - virtual ~IDamageAccumulator() {} -}; - -class DamageAccumulator : public IDamageAccumulator { +class DamageAccumulator { PREVENT_COPY_AND_ASSIGN(DamageAccumulator); public: DamageAccumulator(); @@ -51,17 +40,19 @@ public: // Push a transform node onto the stack. This should be called prior // to any dirty() calls. Subsequent calls to dirty() // will be affected by the transform when popTransform() is called. - virtual void pushTransform(const RenderNode* transform); - virtual void pushTransform(const Matrix4* transform); + void pushTransform(const RenderNode* transform); + void pushTransform(const Matrix4* transform); // Pops a transform node from the stack, propagating the dirty rect // up to the parent node. Returns the IDamageTransform that was just applied - virtual void popTransform(); + void popTransform(); - virtual void dirty(float left, float top, float right, float bottom); + void dirty(float left, float top, float right, float bottom); // Returns the current dirty area, *NOT* transformed by pushed transforms - virtual void peekAtDirty(SkRect* dest); + void peekAtDirty(SkRect* dest); + + void computeCurrentTransform(Matrix4* outMatrix) const; void finish(SkRect* totalDirty); @@ -74,24 +65,6 @@ private: DirtyStack* mHead; }; -class NullDamageAccumulator : public IDamageAccumulator { - PREVENT_COPY_AND_ASSIGN(NullDamageAccumulator); -public: - virtual void pushTransform(const RenderNode* transform) { } - virtual void pushTransform(const Matrix4* transform) { } - virtual void popTransform() { } - virtual void dirty(float left, float top, float right, float bottom) { } - virtual void peekAtDirty(SkRect* dest) { dest->setEmpty(); } - - ANDROID_API static NullDamageAccumulator* instance(); - -private: - NullDamageAccumulator() {} - ~NullDamageAccumulator() {} - - static NullDamageAccumulator sInstance; -}; - } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index f0a6e5534558..94162fcc8118 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -66,7 +66,7 @@ status_t DisplayListRenderer::prepareDirty(float left, float top, "prepareDirty called a second time during a recording!"); mDisplayListData = new DisplayListData(); - initializeSaveStack(0, 0, getWidth(), getHeight()); + initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3()); mDirtyClip = opaque; mRestoreSaveCount = -1; diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index d05cabca7b5a..8639ae1629e6 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -53,6 +53,7 @@ Layer::Layer(RenderState& renderState, const uint32_t layerWidth, const uint32_t deferredList = NULL; convexMask = NULL; caches.resourceCache.incrementRefcount(this); + rendererLightPosDirty = true; } Layer::~Layer() { @@ -80,6 +81,17 @@ void Layer::requireRenderer() { } } +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); @@ -203,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(); @@ -253,7 +266,8 @@ void Layer::flush() { } } -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()); diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 0bf05d0dcf5d..38c29c7796b7 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -86,6 +86,11 @@ public: regionRect.translate(layer.left, layer.top); } + void setWindowTransform(Matrix4& windowTransform) { + cachedInvTransformInWindow.loadInverse(windowTransform); + rendererLightPosDirty = true; + } + void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom); inline uint32_t getWidth() const { @@ -257,10 +262,10 @@ public: return transform; } - void defer(); + void defer(const OpenGLRenderer& rootRenderer); void cancelDefer(); void flush(); - void render(); + void render(const OpenGLRenderer& rootRenderer); /** * Bounds of the layer. @@ -304,6 +309,7 @@ public: private: void requireRenderer(); + void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer); Caches& caches; @@ -383,6 +389,12 @@ private: mat4 transform; /** + * Cached transform of layer in window, updated only on creation / resize + */ + mat4 cachedInvTransformInWindow; + bool rendererLightPosDirty; + + /** * Used to defer display lists when the layer is updated with a * display list. */ diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 3fcfbc1f3fed..721ab3df84fd 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -188,8 +188,7 @@ void OpenGLRenderer::onViewportInitialized() { void OpenGLRenderer::setupFrameState(float left, float top, float right, float bottom, bool opaque) { mCaches.clearGarbage(); - - initializeSaveStack(left, top, right, bottom); + initializeSaveStack(left, top, right, bottom, mLightCenter); mOpaque = opaque; mTilingClip.set(left, top, right, bottom); } @@ -481,9 +480,9 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) { } if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) { - layer->render(); + layer->render(*this); } else { - layer->defer(); + layer->defer(*this); } if (inFrame) { diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index fc95c18e81b8..e9ca5d9c839c 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -345,8 +345,10 @@ public: } #endif - const Vector3& getLightCenter() const { return mLightCenter; } + const Vector3& getLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } float getLightRadius() const { return mLightRadius; } + uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; } + uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; } protected: /** diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index e3732a19bc21..0db6198e7ec2 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -116,6 +116,7 @@ int RenderNode::getDebugSize() { void RenderNode::prepareTree(TreeInfo& info) { ATRACE_CALL(); + LOG_ALWAYS_FATAL_IF(!info.damageAccumulator, "DamageAccumulator missing"); prepareTreeImpl(info); } @@ -163,16 +164,26 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { return; } + bool transformUpdateNeeded = false; if (!mLayer) { mLayer = LayerRenderer::createRenderLayer(info.renderState, getWidth(), getHeight()); applyLayerPropertiesToLayer(info); damageSelf(info); + transformUpdateNeeded = true; } else if (mLayer->layer.getWidth() != getWidth() || mLayer->layer.getHeight() != getHeight()) { if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) { LayerRenderer::destroyLayer(mLayer); mLayer = 0; } damageSelf(info); + transformUpdateNeeded = true; + } + + if (transformUpdateNeeded) { + // update the transform in window of the layer to reset its origin wrt light source position + Matrix4 windowTransform; + info.damageAccumulator->computeCurrentTransform(&windowTransform); + mLayer->setWindowTransform(windowTransform); } SkRect dirty; @@ -406,7 +417,7 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) { * If true3dTransform is set to true, the transform applied to the input matrix will use true 4x4 * matrix computation instead of the Skia 3x3 matrix + camera hackery. */ -void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) { +void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) const { if (properties().getLeft() != 0 || properties().getTop() != 0) { matrix.translate(properties().getLeft(), properties().getTop()); } diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index fa310e072a98..afa17d5c859e 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -174,6 +174,8 @@ public: // UI thread only! ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator); + void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const; + private: typedef key_value_pair_t<float, DrawRenderNodeOp*> ZDrawRenderNodeOpPair; @@ -189,8 +191,6 @@ private: kPositiveZChildren }; - void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false); - void computeOrderingImpl(DrawRenderNodeOp* opState, const SkPath* outlineOfProjectionSurface, Vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface, diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp index 6f19275d0603..ecc47d29a647 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -55,7 +55,8 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags) , empty(false) , alpha(s->alpha) , roundRectClipState(s->roundRectClipState) - , mViewportData(s->mViewportData) { + , mViewportData(s->mViewportData) + , mRelativeLightCenter(s->mRelativeLightCenter) { if (saveFlags & SkCanvas::kMatrix_SaveFlag) { mTransformRoot.load(*s->transform); transform = &mTransformRoot; @@ -200,6 +201,13 @@ void Snapshot::resetClip(float left, float top, float right, float bottom) { /////////////////////////////////////////////////////////////////////////////// void Snapshot::resetTransform(float x, float y, float z) { + // before resetting, map current light pos with inverse of current transform + Vector3 center = mRelativeLightCenter; + mat4 inverse; + inverse.loadInverse(*transform); + inverse.mapPoint3d(center); + mRelativeLightCenter = center; + transform = &mTransformRoot; transform->loadTranslate(x, y, z); } diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index 98e24403aec8..ad4ee9dee6a0 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -161,6 +161,9 @@ public: int getViewportHeight() const { return mViewportData.mHeight; } const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; } + const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; } + void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; } + /** * Sets (and replaces) the current clipping outline */ @@ -302,6 +305,7 @@ private: SkRegion mClipRegionRoot; ViewportData mViewportData; + Vector3 mRelativeLightCenter; }; // class Snapshot diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp index dc41157d5778..06c5ab42592a 100644 --- a/libs/hwui/StatefulBaseRenderer.cpp +++ b/libs/hwui/StatefulBaseRenderer.cpp @@ -35,11 +35,12 @@ StatefulBaseRenderer::StatefulBaseRenderer() } void StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop, - float clipRight, float clipBottom) { + float clipRight, float clipBottom, const Vector3& lightCenter) { mSnapshot = new Snapshot(mFirstSnapshot, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom); mSnapshot->fbo = getTargetFbo(); + mSnapshot->setRelativeLightCenter(lightCenter); mSaveCount = 1; } diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h index 6d83b4ca3dd8..3957d36fd13a 100644 --- a/libs/hwui/StatefulBaseRenderer.h +++ b/libs/hwui/StatefulBaseRenderer.h @@ -52,7 +52,8 @@ public: * the render target. */ virtual void setViewport(int width, int height); - void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom); + void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, + const Vector3& lightCenter); // getters bool hasRectToRectTransform() const { diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp index c5fc21fcfa90..0a9aeb88e646 100644 --- a/libs/hwui/TessellationCache.cpp +++ b/libs/hwui/TessellationCache.cpp @@ -14,9 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - #include <utils/JenkinsHash.h> #include <utils/Trace.h> diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h index de09755803b6..331f1574ff17 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -65,7 +65,7 @@ public: , frameTimeMs(0) , animationHook(NULL) , prepareTextures(mode == MODE_FULL) - , damageAccumulator(NullDamageAccumulator::instance()) + , damageAccumulator(NULL) , renderState(renderState) , renderer(NULL) , errorHandler(NULL) @@ -88,8 +88,9 @@ public: // TODO: Remove this? Currently this is used to signal to stop preparing // textures if we run out of cache space. bool prepareTextures; - // Must not be null - IDamageAccumulator* damageAccumulator; + + // Must not be null during actual usage + DamageAccumulator* damageAccumulator; RenderState& renderState; // The renderer that will be drawing the next frame. Use this to push any // layer updates or similar. May be NULL. diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 756f6606375d..e673b0d16bab 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "CanvasContext" - #include "CanvasContext.h" #include <private/hwui/DrawGlInfo.h> diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 986e80805a00..d9b96f6c9851 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "RenderProxy" - #include "RenderProxy.h" #include "CanvasContext.h" diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 68033dca7c55..403e1644bc7b 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "RenderThread" - #include "RenderThread.h" #if defined(HAVE_PTHREADS) |