diff options
-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) |