diff options
author | Chris Craik <ccraik@google.com> | 2014-08-14 13:34:01 -0700 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2014-08-15 00:59:44 +0000 |
commit | 69e5adffb19135d51bde8e458f4907d7265f3e23 (patch) | |
tree | 022fc23512ae5adfbe3f86351305bc9f4538a68a /libs/hwui | |
parent | e222e359a0aab985488a711f6edb76820fe8c6df (diff) | |
download | frameworks_base-69e5adffb19135d51bde8e458f4907d7265f3e23.zip frameworks_base-69e5adffb19135d51bde8e458f4907d7265f3e23.tar.gz frameworks_base-69e5adffb19135d51bde8e458f4907d7265f3e23.tar.bz2 |
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
Diffstat (limited to 'libs/hwui')
-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 5ecd77a..78d569d 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 15bed58..054a164 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 90d9425..6f0bd8c 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 f0a6e55..94162fc 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 d05cabc..8639ae1 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 0bf05d0..38c29c7 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 3fcfbc1..721ab3d 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 fc95c18..e9ca5d9 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 e3732a1..0db6198 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 fa310e0..afa17d5 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 6f19275..ecc47d2 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 98e2440..ad4ee9d 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 dc41157..06c5ab4 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 6d83b4c..3957d36 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 c5fc21f..0a9aeb8 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 de09755..331f157 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 756f660..e673b0d 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 986e808..d9b96f6 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 68033dc..403e164 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) |