Loading libs/hwui/Android.mk +4 −4 Original line number Diff line number Diff line Loading @@ -25,10 +25,9 @@ ifeq ($(USE_OPENGL_RENDERER),true) Animator.cpp \ AnimatorManager.cpp \ AssetAtlas.cpp \ DamageAccumulator.cpp \ FontRenderer.cpp \ GammaFontRenderer.cpp \ Caches.cpp \ CanvasState.cpp \ DamageAccumulator.cpp \ DisplayList.cpp \ DeferredDisplayList.cpp \ DeferredLayerUpdater.cpp \ Loading @@ -38,6 +37,8 @@ ifeq ($(USE_OPENGL_RENDERER),true) DrawProfiler.cpp \ Extensions.cpp \ FboCache.cpp \ FontRenderer.cpp \ GammaFontRenderer.cpp \ GradientCache.cpp \ Image.cpp \ Interpolator.cpp \ Loading @@ -62,7 +63,6 @@ ifeq ($(USE_OPENGL_RENDERER),true) SkiaShader.cpp \ Snapshot.cpp \ SpotShadow.cpp \ StatefulBaseRenderer.cpp \ Stencil.cpp \ TessellationCache.cpp \ Texture.cpp \ Loading libs/hwui/StatefulBaseRenderer.cpp→libs/hwui/CanvasState.cpp +41 −48 Original line number Diff line number Diff line Loading @@ -14,41 +14,45 @@ * limitations under the License. */ #define LOG_TAG "OpenGLRenderer" #include <SkCanvas.h> #include "StatefulBaseRenderer.h" #include "CanvasState.h" #include "utils/MathUtils.h" namespace android { namespace uirenderer { StatefulBaseRenderer::StatefulBaseRenderer() CanvasState::CanvasState(CanvasStateClient& renderer) : mDirtyClip(false) , mWidth(-1) , mHeight(-1) , mSaveCount(1) , mFirstSnapshot(new Snapshot) , mCanvas(renderer) , mSnapshot(mFirstSnapshot) { } void StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop, CanvasState::~CanvasState() { } void CanvasState::initializeSaveStack(float clipLeft, float clipTop, 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->fbo = mCanvas.onGetTargetFbo(); mSnapshot->setRelativeLightCenter(lightCenter); mSaveCount = 1; } void StatefulBaseRenderer::setViewport(int width, int height) { void CanvasState::setViewport(int width, int height) { mWidth = width; mHeight = height; mFirstSnapshot->initializeViewport(width, height); onViewportInitialized(); mCanvas.onViewportInitialized(); // create a temporary 1st snapshot, so old snapshots are released, // and viewport can be queried safely. Loading @@ -63,24 +67,24 @@ void StatefulBaseRenderer::setViewport(int width, int height) { /////////////////////////////////////////////////////////////////////////////// /** * Non-virtual implementation of save, guaranteed to save without side-effects * Guaranteed to save without side-effects * * The approach here and in restoreSnapshot(), allows subclasses to directly manipulate the save * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save * stack, and ensures restoreToCount() doesn't call back into subclass overrides. */ int StatefulBaseRenderer::saveSnapshot(int flags) { int CanvasState::saveSnapshot(int flags) { mSnapshot = new Snapshot(mSnapshot, flags); return mSaveCount++; } int StatefulBaseRenderer::save(int flags) { int CanvasState::save(int flags) { return saveSnapshot(flags); } /** * Non-virtual implementation of restore, guaranteed to restore without side-effects. * Guaranteed to restore without side-effects. */ void StatefulBaseRenderer::restoreSnapshot() { void CanvasState::restoreSnapshot() { sp<Snapshot> toRemove = mSnapshot; sp<Snapshot> toRestore = mSnapshot->previous; Loading @@ -88,16 +92,16 @@ void StatefulBaseRenderer::restoreSnapshot() { mSnapshot = toRestore; // subclass handles restore implementation onSnapshotRestored(*toRemove, *toRestore); mCanvas.onSnapshotRestored(*toRemove, *toRestore); } void StatefulBaseRenderer::restore() { void CanvasState::restore() { if (mSaveCount > 1) { restoreSnapshot(); } } void StatefulBaseRenderer::restoreToCount(int saveCount) { void CanvasState::restoreToCount(int saveCount) { if (saveCount < 1) saveCount = 1; while (mSaveCount > saveCount) { Loading @@ -109,40 +113,40 @@ void StatefulBaseRenderer::restoreToCount(int saveCount) { // Matrix /////////////////////////////////////////////////////////////////////////////// void StatefulBaseRenderer::getMatrix(SkMatrix* matrix) const { void CanvasState::getMatrix(SkMatrix* matrix) const { mSnapshot->transform->copyTo(*matrix); } void StatefulBaseRenderer::translate(float dx, float dy, float dz) { void CanvasState::translate(float dx, float dy, float dz) { mSnapshot->transform->translate(dx, dy, dz); } void StatefulBaseRenderer::rotate(float degrees) { void CanvasState::rotate(float degrees) { mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); } void StatefulBaseRenderer::scale(float sx, float sy) { void CanvasState::scale(float sx, float sy) { mSnapshot->transform->scale(sx, sy, 1.0f); } void StatefulBaseRenderer::skew(float sx, float sy) { void CanvasState::skew(float sx, float sy) { mSnapshot->transform->skew(sx, sy); } void StatefulBaseRenderer::setMatrix(const SkMatrix& matrix) { void CanvasState::setMatrix(const SkMatrix& matrix) { mSnapshot->transform->load(matrix); } void StatefulBaseRenderer::setMatrix(const Matrix4& matrix) { void CanvasState::setMatrix(const Matrix4& matrix) { mSnapshot->transform->load(matrix); } void StatefulBaseRenderer::concatMatrix(const SkMatrix& matrix) { void CanvasState::concatMatrix(const SkMatrix& matrix) { mat4 transform(matrix); mSnapshot->transform->multiply(transform); } void StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { void CanvasState::concatMatrix(const Matrix4& matrix) { mSnapshot->transform->multiply(matrix); } Loading @@ -150,7 +154,7 @@ void StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { // Clip /////////////////////////////////////////////////////////////////////////////// bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { if (CC_LIKELY(currentTransform()->rectToRect())) { mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op); return !mSnapshot->clipRect->isEmpty(); Loading @@ -159,10 +163,10 @@ bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bo SkPath path; path.addRect(left, top, right, bottom); return StatefulBaseRenderer::clipPath(&path, op); return CanvasState::clipPath(&path, op); } bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) { SkMatrix transform; currentTransform()->copyTo(transform); Loading @@ -189,12 +193,12 @@ bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { return !mSnapshot->clipRect->isEmpty(); } bool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) { mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op); return !mSnapshot->clipRect->isEmpty(); } void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { void CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { Rect bounds; float radius; if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported Loading @@ -209,7 +213,7 @@ void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const } } void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, void CanvasState::setClippingRoundRect(LinearAllocator& allocator, const Rect& rect, float radius, bool highPriority) { mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); } Loading @@ -229,7 +233,7 @@ void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, * @param snapOut if set, the geometry will be treated as having an AA ramp. * See Rect::snapGeometryToPixelBoundaries() */ bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, bool CanvasState::calculateQuickRejectForScissor(float left, float top, float right, float bottom, bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const { Loading Loading @@ -259,18 +263,7 @@ bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, return false; } /** * Returns false if drawing won't be clipped out. * * Makes the decision conservatively, by rounding out the mapped rect before comparing with the * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but * rejection is still desired. * * This function, unlike quickRejectSetupScissor, should be used where precise geometry information * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass * rejection where precise rejection isn't important, or precise information isn't available. */ bool StatefulBaseRenderer::quickRejectConservative(float left, float top, bool CanvasState::quickRejectConservative(float left, float top, float right, float bottom) const { if (mSnapshot->isIgnored() || bottom <= top || right <= left) { return true; Loading @@ -288,5 +281,5 @@ bool StatefulBaseRenderer::quickRejectConservative(float left, float top, return false; } }; // namespace uirenderer }; // namespace android } // namespace uirenderer } // namespace android libs/hwui/StatefulBaseRenderer.h→libs/hwui/CanvasState.h +196 −0 Original line number Diff line number Diff line Loading @@ -14,157 +14,183 @@ * limitations under the License. */ #ifndef ANDROID_HWUI_STATEFUL_BASE_RENDERER_H #define ANDROID_HWUI_STATEFUL_BASE_RENDERER_H #ifndef ANDROID_HWUI_CANVAS_STATE_H #define ANDROID_HWUI_CANVAS_STATE_H #include <utils/RefBase.h> #include <SkMatrix.h> #include <SkPath.h> #include <SkRegion.h> #include "Renderer.h" #include "Snapshot.h" namespace android { namespace uirenderer { /** * Abstract Renderer subclass, which implements Canvas state methods. * Abstract base class for any class containing CanvasState. * Defines three mandatory callbacks. */ class CanvasStateClient { public: CanvasStateClient() { } virtual ~CanvasStateClient() { } /** * Callback allowing embedder to take actions in the middle of a * setViewport() call. */ virtual void onViewportInitialized() = 0; /** * Callback allowing embedder to take actions in the middle of a * restore() call. May be called several times sequentially. */ virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0; /** * Allows subclasses to control what value is stored in snapshot's * fbo field in * initializeSaveStack. */ virtual GLuint onGetTargetFbo() const = 0; }; // class CanvasStateClient /** * Implements Canvas state methods on behalf of Renderers. * * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the * Renderer interface. Drawing and recording classes that extend StatefulBaseRenderer will have * Renderer interface. Drawing and recording classes that include a CanvasState will have * different use cases: * * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself. * * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations * to StatefulBaseRenderer, so that not only will querying operations work (getClip/Matrix), but so * to CanvasState, so that not only will querying operations work (getClip/Matrix), but so * that quickRejection can also be used. */ class StatefulBaseRenderer : public Renderer { public: StatefulBaseRenderer(); virtual void prepare(bool opaque) { prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque); } class CanvasState { public: CanvasState(CanvasStateClient& renderer); ~CanvasState(); /** * Initialize the first snapshot, computing the projection matrix, and stores the dimensions of * the render target. * Initializes the first snapshot, computing the projection matrix, * and stores the dimensions of the render target. */ virtual void setViewport(int width, int height); void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, const Vector3& lightCenter); // getters void setViewport(int width, int height); bool hasRectToRectTransform() const { return CC_LIKELY(currentTransform()->rectToRect()); } // Save (layer) virtual int getSaveCount() const { return mSaveCount; } virtual int save(int flags); virtual void restore(); virtual void restoreToCount(int saveCount); //virtual int saveLayer(float left, float top, float right, float bottom, // int alpha, SkXfermode::Mode mode, int flags); int getSaveCount() const { return mSaveCount; } int save(int flags); void restore(); void restoreToCount(int saveCount); // Save/Restore without side-effects int saveSnapshot(int flags); void restoreSnapshot(); // Matrix virtual void getMatrix(SkMatrix* outMatrix) const; virtual void translate(float dx, float dy, float dz = 0.0f); virtual void rotate(float degrees); virtual void scale(float sx, float sy); virtual void skew(float sx, float sy); void getMatrix(SkMatrix* outMatrix) const; void translate(float dx, float dy, float dz = 0.0f); void rotate(float degrees); void scale(float sx, float sy); void skew(float sx, float sy); virtual void setMatrix(const SkMatrix& matrix); void setMatrix(const SkMatrix& matrix); void setMatrix(const Matrix4& matrix); // internal only convenience method virtual void concatMatrix(const SkMatrix& matrix); void concatMatrix(const SkMatrix& matrix); void concatMatrix(const Matrix4& matrix); // internal only convenience method // Clip virtual const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } bool quickRejectConservative(float left, float top, float right, float bottom) const; virtual bool quickRejectConservative(float left, float top, float right, float bottom) const; bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); bool clipPath(const SkPath* path, SkRegion::Op op); bool clipRegion(const SkRegion* region, SkRegion::Op op); virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); virtual bool clipPath(const SkPath* path, SkRegion::Op op); virtual bool clipRegion(const SkRegion* region, SkRegion::Op op); bool isCurrentClipSimple() const { return currentSnapshot()->clipRegion->isEmpty(); } /** * Does not support different clipping Ops (that is, every call to setClippingOutline is * effectively using SkRegion::kReplaceOp) * * The clipping outline is independent from the regular clip. * Sets a "clipping outline", which is independent from the regular clip. * Currently only supports rectangles or rounded rectangles; passing in a * more complicated outline fails silently. Replaces any previous clipping * outline. */ void setClippingOutline(LinearAllocator& allocator, const Outline* outline); void setClippingRoundRect(LinearAllocator& allocator, const Rect& rect, float radius, bool highPriority = true); inline const mat4* currentTransform() const { return mSnapshot->transform; } protected: const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } int getWidth() { return mWidth; } int getHeight() { return mHeight; } // Save int saveSnapshot(int flags); void restoreSnapshot(); // allows subclasses to control what value is stored in snapshot's fbo field in // initializeSaveStack virtual GLuint getTargetFbo() const { return -1; } // Clip bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; /** * Called just after a restore has occurred. The 'removed' snapshot popped from the stack, * 'restored' snapshot has become the top/current. * * Subclasses can override this method to handle layer restoration * Returns true if drawing in the rectangle (left, top, right, bottom) * will be clipped out. Is conservative: might return false when subpixel- * perfect tests would return true. */ virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}; virtual void onViewportInitialized() {}; bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; inline const Rect* currentClipRect() const { return mSnapshot->clipRect; } void setDirtyClip(bool opaque) { mDirtyClip = opaque; } bool getDirtyClip() const { return mDirtyClip; } void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; } void setEmpty(bool value) { mSnapshot->empty = value; } void setInvisible(bool value) { mSnapshot->invisible = value; } inline const mat4* currentTransform() const { return currentSnapshot()->transform; } inline const Rect* currentClipRect() const { return currentSnapshot()->clipRect; } inline Region* currentRegion() const { return currentSnapshot()->region; } inline int currentFlags() const { return currentSnapshot()->flags; } const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); } int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); } int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); } int getWidth() { return mWidth; } int getHeight() { return mHeight; } inline const Snapshot* currentSnapshot() const { return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get(); } inline Snapshot* writableSnapshot() { return mSnapshot.get(); } inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); } inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); } private: /// No default constructor - must supply a CanvasStateClient (mCanvas). CanvasState(); // indicites that the clip has been changed since the last time it was consumed /// indicates that the clip has been changed since the last time it was consumed bool mDirtyClip; private: // Dimensions of the drawing surface /// Dimensions of the drawing surface int mWidth, mHeight; // Number of saved states /// Number of saved states int mSaveCount; // Base state /// Base state sp<Snapshot> mFirstSnapshot; protected: // Current state // TODO: should become private, once hooks needed by OpenGLRenderer are added /// Host providing callbacks CanvasStateClient& mCanvas; /// Current state sp<Snapshot> mSnapshot; }; // class StatefulBaseRenderer }; // class CanvasState }; // namespace uirenderer }; // namespace android #endif // ANDROID_HWUI_STATEFUL_BASE_RENDERER_H #endif // ANDROID_HWUI_CANVAS_STATE_H libs/hwui/DisplayListRenderer.cpp +18 −17 Original line number Diff line number Diff line Loading @@ -32,7 +32,8 @@ namespace android { namespace uirenderer { DisplayListRenderer::DisplayListRenderer() : mCaches(Caches::getInstance()) : mState(*this) , mCaches(Caches::getInstance()) , mDisplayListData(NULL) , mTranslateX(0.0f) , mTranslateY(0.0f) Loading Loading @@ -66,10 +67,10 @@ void DisplayListRenderer::prepareDirty(float left, float top, "prepareDirty called a second time during a recording!"); mDisplayListData = new DisplayListData(); initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3()); mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3()); mDeferredBarrierType = kBarrier_InOrder; mDirtyClip = opaque; mState.setDirtyClip(opaque); mRestoreSaveCount = -1; } Loading @@ -93,7 +94,7 @@ void DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { int DisplayListRenderer::save(int flags) { addStateOp(new (alloc()) SaveOp(flags)); return StatefulBaseRenderer::save(flags); return mState.save(flags); } void DisplayListRenderer::restore() { Loading @@ -104,13 +105,13 @@ void DisplayListRenderer::restore() { mRestoreSaveCount--; flushTranslate(); StatefulBaseRenderer::restore(); mState.restore(); } void DisplayListRenderer::restoreToCount(int saveCount) { mRestoreSaveCount = saveCount; flushTranslate(); StatefulBaseRenderer::restoreToCount(saveCount); mState.restoreToCount(saveCount); } int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, Loading @@ -120,7 +121,7 @@ int DisplayListRenderer::saveLayer(float left, float top, float right, float bot paint = refPaint(paint); addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags)); return StatefulBaseRenderer::save(flags); return mState.save(flags); } void DisplayListRenderer::translate(float dx, float dy, float dz) { Loading @@ -129,50 +130,50 @@ void DisplayListRenderer::translate(float dx, float dy, float dz) { mTranslateX += dx; mTranslateY += dy; flushRestoreToCount(); StatefulBaseRenderer::translate(dx, dy, dz); mState.translate(dx, dy, dz); } void DisplayListRenderer::rotate(float degrees) { addStateOp(new (alloc()) RotateOp(degrees)); StatefulBaseRenderer::rotate(degrees); mState.rotate(degrees); } void DisplayListRenderer::scale(float sx, float sy) { addStateOp(new (alloc()) ScaleOp(sx, sy)); StatefulBaseRenderer::scale(sx, sy); mState.scale(sx, sy); } void DisplayListRenderer::skew(float sx, float sy) { addStateOp(new (alloc()) SkewOp(sx, sy)); StatefulBaseRenderer::skew(sx, sy); mState.skew(sx, sy); } void DisplayListRenderer::setMatrix(const SkMatrix& matrix) { addStateOp(new (alloc()) SetMatrixOp(matrix)); StatefulBaseRenderer::setMatrix(matrix); mState.setMatrix(matrix); } void DisplayListRenderer::concatMatrix(const SkMatrix& matrix) { addStateOp(new (alloc()) ConcatMatrixOp(matrix)); StatefulBaseRenderer::concatMatrix(matrix); mState.concatMatrix(matrix); } bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); return StatefulBaseRenderer::clipRect(left, top, right, bottom, op); return mState.clipRect(left, top, right, bottom, op); } bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) { path = refPath(path); addStateOp(new (alloc()) ClipPathOp(path, op)); return StatefulBaseRenderer::clipPath(path, op); return mState.clipPath(path, op); } bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { region = refRegion(region); addStateOp(new (alloc()) ClipRegionOp(region, op)); return StatefulBaseRenderer::clipRegion(region, op); return mState.clipRegion(region, op); } void DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) { Loading @@ -180,7 +181,7 @@ void DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, in // dirty is an out parameter and should not be recorded, // it matters only when replaying the display list DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *currentTransform()); DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *mState.currentTransform()); addRenderNodeOp(op); } Loading libs/hwui/DisplayListRenderer.h +29 −3 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
libs/hwui/Android.mk +4 −4 Original line number Diff line number Diff line Loading @@ -25,10 +25,9 @@ ifeq ($(USE_OPENGL_RENDERER),true) Animator.cpp \ AnimatorManager.cpp \ AssetAtlas.cpp \ DamageAccumulator.cpp \ FontRenderer.cpp \ GammaFontRenderer.cpp \ Caches.cpp \ CanvasState.cpp \ DamageAccumulator.cpp \ DisplayList.cpp \ DeferredDisplayList.cpp \ DeferredLayerUpdater.cpp \ Loading @@ -38,6 +37,8 @@ ifeq ($(USE_OPENGL_RENDERER),true) DrawProfiler.cpp \ Extensions.cpp \ FboCache.cpp \ FontRenderer.cpp \ GammaFontRenderer.cpp \ GradientCache.cpp \ Image.cpp \ Interpolator.cpp \ Loading @@ -62,7 +63,6 @@ ifeq ($(USE_OPENGL_RENDERER),true) SkiaShader.cpp \ Snapshot.cpp \ SpotShadow.cpp \ StatefulBaseRenderer.cpp \ Stencil.cpp \ TessellationCache.cpp \ Texture.cpp \ Loading
libs/hwui/StatefulBaseRenderer.cpp→libs/hwui/CanvasState.cpp +41 −48 Original line number Diff line number Diff line Loading @@ -14,41 +14,45 @@ * limitations under the License. */ #define LOG_TAG "OpenGLRenderer" #include <SkCanvas.h> #include "StatefulBaseRenderer.h" #include "CanvasState.h" #include "utils/MathUtils.h" namespace android { namespace uirenderer { StatefulBaseRenderer::StatefulBaseRenderer() CanvasState::CanvasState(CanvasStateClient& renderer) : mDirtyClip(false) , mWidth(-1) , mHeight(-1) , mSaveCount(1) , mFirstSnapshot(new Snapshot) , mCanvas(renderer) , mSnapshot(mFirstSnapshot) { } void StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop, CanvasState::~CanvasState() { } void CanvasState::initializeSaveStack(float clipLeft, float clipTop, 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->fbo = mCanvas.onGetTargetFbo(); mSnapshot->setRelativeLightCenter(lightCenter); mSaveCount = 1; } void StatefulBaseRenderer::setViewport(int width, int height) { void CanvasState::setViewport(int width, int height) { mWidth = width; mHeight = height; mFirstSnapshot->initializeViewport(width, height); onViewportInitialized(); mCanvas.onViewportInitialized(); // create a temporary 1st snapshot, so old snapshots are released, // and viewport can be queried safely. Loading @@ -63,24 +67,24 @@ void StatefulBaseRenderer::setViewport(int width, int height) { /////////////////////////////////////////////////////////////////////////////// /** * Non-virtual implementation of save, guaranteed to save without side-effects * Guaranteed to save without side-effects * * The approach here and in restoreSnapshot(), allows subclasses to directly manipulate the save * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save * stack, and ensures restoreToCount() doesn't call back into subclass overrides. */ int StatefulBaseRenderer::saveSnapshot(int flags) { int CanvasState::saveSnapshot(int flags) { mSnapshot = new Snapshot(mSnapshot, flags); return mSaveCount++; } int StatefulBaseRenderer::save(int flags) { int CanvasState::save(int flags) { return saveSnapshot(flags); } /** * Non-virtual implementation of restore, guaranteed to restore without side-effects. * Guaranteed to restore without side-effects. */ void StatefulBaseRenderer::restoreSnapshot() { void CanvasState::restoreSnapshot() { sp<Snapshot> toRemove = mSnapshot; sp<Snapshot> toRestore = mSnapshot->previous; Loading @@ -88,16 +92,16 @@ void StatefulBaseRenderer::restoreSnapshot() { mSnapshot = toRestore; // subclass handles restore implementation onSnapshotRestored(*toRemove, *toRestore); mCanvas.onSnapshotRestored(*toRemove, *toRestore); } void StatefulBaseRenderer::restore() { void CanvasState::restore() { if (mSaveCount > 1) { restoreSnapshot(); } } void StatefulBaseRenderer::restoreToCount(int saveCount) { void CanvasState::restoreToCount(int saveCount) { if (saveCount < 1) saveCount = 1; while (mSaveCount > saveCount) { Loading @@ -109,40 +113,40 @@ void StatefulBaseRenderer::restoreToCount(int saveCount) { // Matrix /////////////////////////////////////////////////////////////////////////////// void StatefulBaseRenderer::getMatrix(SkMatrix* matrix) const { void CanvasState::getMatrix(SkMatrix* matrix) const { mSnapshot->transform->copyTo(*matrix); } void StatefulBaseRenderer::translate(float dx, float dy, float dz) { void CanvasState::translate(float dx, float dy, float dz) { mSnapshot->transform->translate(dx, dy, dz); } void StatefulBaseRenderer::rotate(float degrees) { void CanvasState::rotate(float degrees) { mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); } void StatefulBaseRenderer::scale(float sx, float sy) { void CanvasState::scale(float sx, float sy) { mSnapshot->transform->scale(sx, sy, 1.0f); } void StatefulBaseRenderer::skew(float sx, float sy) { void CanvasState::skew(float sx, float sy) { mSnapshot->transform->skew(sx, sy); } void StatefulBaseRenderer::setMatrix(const SkMatrix& matrix) { void CanvasState::setMatrix(const SkMatrix& matrix) { mSnapshot->transform->load(matrix); } void StatefulBaseRenderer::setMatrix(const Matrix4& matrix) { void CanvasState::setMatrix(const Matrix4& matrix) { mSnapshot->transform->load(matrix); } void StatefulBaseRenderer::concatMatrix(const SkMatrix& matrix) { void CanvasState::concatMatrix(const SkMatrix& matrix) { mat4 transform(matrix); mSnapshot->transform->multiply(transform); } void StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { void CanvasState::concatMatrix(const Matrix4& matrix) { mSnapshot->transform->multiply(matrix); } Loading @@ -150,7 +154,7 @@ void StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { // Clip /////////////////////////////////////////////////////////////////////////////// bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { if (CC_LIKELY(currentTransform()->rectToRect())) { mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op); return !mSnapshot->clipRect->isEmpty(); Loading @@ -159,10 +163,10 @@ bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bo SkPath path; path.addRect(left, top, right, bottom); return StatefulBaseRenderer::clipPath(&path, op); return CanvasState::clipPath(&path, op); } bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) { SkMatrix transform; currentTransform()->copyTo(transform); Loading @@ -189,12 +193,12 @@ bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { return !mSnapshot->clipRect->isEmpty(); } bool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) { mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op); return !mSnapshot->clipRect->isEmpty(); } void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { void CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { Rect bounds; float radius; if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported Loading @@ -209,7 +213,7 @@ void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const } } void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, void CanvasState::setClippingRoundRect(LinearAllocator& allocator, const Rect& rect, float radius, bool highPriority) { mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); } Loading @@ -229,7 +233,7 @@ void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, * @param snapOut if set, the geometry will be treated as having an AA ramp. * See Rect::snapGeometryToPixelBoundaries() */ bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, bool CanvasState::calculateQuickRejectForScissor(float left, float top, float right, float bottom, bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const { Loading Loading @@ -259,18 +263,7 @@ bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, return false; } /** * Returns false if drawing won't be clipped out. * * Makes the decision conservatively, by rounding out the mapped rect before comparing with the * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but * rejection is still desired. * * This function, unlike quickRejectSetupScissor, should be used where precise geometry information * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass * rejection where precise rejection isn't important, or precise information isn't available. */ bool StatefulBaseRenderer::quickRejectConservative(float left, float top, bool CanvasState::quickRejectConservative(float left, float top, float right, float bottom) const { if (mSnapshot->isIgnored() || bottom <= top || right <= left) { return true; Loading @@ -288,5 +281,5 @@ bool StatefulBaseRenderer::quickRejectConservative(float left, float top, return false; } }; // namespace uirenderer }; // namespace android } // namespace uirenderer } // namespace android
libs/hwui/StatefulBaseRenderer.h→libs/hwui/CanvasState.h +196 −0 Original line number Diff line number Diff line Loading @@ -14,157 +14,183 @@ * limitations under the License. */ #ifndef ANDROID_HWUI_STATEFUL_BASE_RENDERER_H #define ANDROID_HWUI_STATEFUL_BASE_RENDERER_H #ifndef ANDROID_HWUI_CANVAS_STATE_H #define ANDROID_HWUI_CANVAS_STATE_H #include <utils/RefBase.h> #include <SkMatrix.h> #include <SkPath.h> #include <SkRegion.h> #include "Renderer.h" #include "Snapshot.h" namespace android { namespace uirenderer { /** * Abstract Renderer subclass, which implements Canvas state methods. * Abstract base class for any class containing CanvasState. * Defines three mandatory callbacks. */ class CanvasStateClient { public: CanvasStateClient() { } virtual ~CanvasStateClient() { } /** * Callback allowing embedder to take actions in the middle of a * setViewport() call. */ virtual void onViewportInitialized() = 0; /** * Callback allowing embedder to take actions in the middle of a * restore() call. May be called several times sequentially. */ virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0; /** * Allows subclasses to control what value is stored in snapshot's * fbo field in * initializeSaveStack. */ virtual GLuint onGetTargetFbo() const = 0; }; // class CanvasStateClient /** * Implements Canvas state methods on behalf of Renderers. * * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the * Renderer interface. Drawing and recording classes that extend StatefulBaseRenderer will have * Renderer interface. Drawing and recording classes that include a CanvasState will have * different use cases: * * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself. * * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations * to StatefulBaseRenderer, so that not only will querying operations work (getClip/Matrix), but so * to CanvasState, so that not only will querying operations work (getClip/Matrix), but so * that quickRejection can also be used. */ class StatefulBaseRenderer : public Renderer { public: StatefulBaseRenderer(); virtual void prepare(bool opaque) { prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque); } class CanvasState { public: CanvasState(CanvasStateClient& renderer); ~CanvasState(); /** * Initialize the first snapshot, computing the projection matrix, and stores the dimensions of * the render target. * Initializes the first snapshot, computing the projection matrix, * and stores the dimensions of the render target. */ virtual void setViewport(int width, int height); void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, const Vector3& lightCenter); // getters void setViewport(int width, int height); bool hasRectToRectTransform() const { return CC_LIKELY(currentTransform()->rectToRect()); } // Save (layer) virtual int getSaveCount() const { return mSaveCount; } virtual int save(int flags); virtual void restore(); virtual void restoreToCount(int saveCount); //virtual int saveLayer(float left, float top, float right, float bottom, // int alpha, SkXfermode::Mode mode, int flags); int getSaveCount() const { return mSaveCount; } int save(int flags); void restore(); void restoreToCount(int saveCount); // Save/Restore without side-effects int saveSnapshot(int flags); void restoreSnapshot(); // Matrix virtual void getMatrix(SkMatrix* outMatrix) const; virtual void translate(float dx, float dy, float dz = 0.0f); virtual void rotate(float degrees); virtual void scale(float sx, float sy); virtual void skew(float sx, float sy); void getMatrix(SkMatrix* outMatrix) const; void translate(float dx, float dy, float dz = 0.0f); void rotate(float degrees); void scale(float sx, float sy); void skew(float sx, float sy); virtual void setMatrix(const SkMatrix& matrix); void setMatrix(const SkMatrix& matrix); void setMatrix(const Matrix4& matrix); // internal only convenience method virtual void concatMatrix(const SkMatrix& matrix); void concatMatrix(const SkMatrix& matrix); void concatMatrix(const Matrix4& matrix); // internal only convenience method // Clip virtual const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } bool quickRejectConservative(float left, float top, float right, float bottom) const; virtual bool quickRejectConservative(float left, float top, float right, float bottom) const; bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); bool clipPath(const SkPath* path, SkRegion::Op op); bool clipRegion(const SkRegion* region, SkRegion::Op op); virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); virtual bool clipPath(const SkPath* path, SkRegion::Op op); virtual bool clipRegion(const SkRegion* region, SkRegion::Op op); bool isCurrentClipSimple() const { return currentSnapshot()->clipRegion->isEmpty(); } /** * Does not support different clipping Ops (that is, every call to setClippingOutline is * effectively using SkRegion::kReplaceOp) * * The clipping outline is independent from the regular clip. * Sets a "clipping outline", which is independent from the regular clip. * Currently only supports rectangles or rounded rectangles; passing in a * more complicated outline fails silently. Replaces any previous clipping * outline. */ void setClippingOutline(LinearAllocator& allocator, const Outline* outline); void setClippingRoundRect(LinearAllocator& allocator, const Rect& rect, float radius, bool highPriority = true); inline const mat4* currentTransform() const { return mSnapshot->transform; } protected: const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } int getWidth() { return mWidth; } int getHeight() { return mHeight; } // Save int saveSnapshot(int flags); void restoreSnapshot(); // allows subclasses to control what value is stored in snapshot's fbo field in // initializeSaveStack virtual GLuint getTargetFbo() const { return -1; } // Clip bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; /** * Called just after a restore has occurred. The 'removed' snapshot popped from the stack, * 'restored' snapshot has become the top/current. * * Subclasses can override this method to handle layer restoration * Returns true if drawing in the rectangle (left, top, right, bottom) * will be clipped out. Is conservative: might return false when subpixel- * perfect tests would return true. */ virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}; virtual void onViewportInitialized() {}; bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; inline const Rect* currentClipRect() const { return mSnapshot->clipRect; } void setDirtyClip(bool opaque) { mDirtyClip = opaque; } bool getDirtyClip() const { return mDirtyClip; } void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; } void setEmpty(bool value) { mSnapshot->empty = value; } void setInvisible(bool value) { mSnapshot->invisible = value; } inline const mat4* currentTransform() const { return currentSnapshot()->transform; } inline const Rect* currentClipRect() const { return currentSnapshot()->clipRect; } inline Region* currentRegion() const { return currentSnapshot()->region; } inline int currentFlags() const { return currentSnapshot()->flags; } const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); } int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); } int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); } int getWidth() { return mWidth; } int getHeight() { return mHeight; } inline const Snapshot* currentSnapshot() const { return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get(); } inline Snapshot* writableSnapshot() { return mSnapshot.get(); } inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); } inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); } private: /// No default constructor - must supply a CanvasStateClient (mCanvas). CanvasState(); // indicites that the clip has been changed since the last time it was consumed /// indicates that the clip has been changed since the last time it was consumed bool mDirtyClip; private: // Dimensions of the drawing surface /// Dimensions of the drawing surface int mWidth, mHeight; // Number of saved states /// Number of saved states int mSaveCount; // Base state /// Base state sp<Snapshot> mFirstSnapshot; protected: // Current state // TODO: should become private, once hooks needed by OpenGLRenderer are added /// Host providing callbacks CanvasStateClient& mCanvas; /// Current state sp<Snapshot> mSnapshot; }; // class StatefulBaseRenderer }; // class CanvasState }; // namespace uirenderer }; // namespace android #endif // ANDROID_HWUI_STATEFUL_BASE_RENDERER_H #endif // ANDROID_HWUI_CANVAS_STATE_H
libs/hwui/DisplayListRenderer.cpp +18 −17 Original line number Diff line number Diff line Loading @@ -32,7 +32,8 @@ namespace android { namespace uirenderer { DisplayListRenderer::DisplayListRenderer() : mCaches(Caches::getInstance()) : mState(*this) , mCaches(Caches::getInstance()) , mDisplayListData(NULL) , mTranslateX(0.0f) , mTranslateY(0.0f) Loading Loading @@ -66,10 +67,10 @@ void DisplayListRenderer::prepareDirty(float left, float top, "prepareDirty called a second time during a recording!"); mDisplayListData = new DisplayListData(); initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3()); mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3()); mDeferredBarrierType = kBarrier_InOrder; mDirtyClip = opaque; mState.setDirtyClip(opaque); mRestoreSaveCount = -1; } Loading @@ -93,7 +94,7 @@ void DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { int DisplayListRenderer::save(int flags) { addStateOp(new (alloc()) SaveOp(flags)); return StatefulBaseRenderer::save(flags); return mState.save(flags); } void DisplayListRenderer::restore() { Loading @@ -104,13 +105,13 @@ void DisplayListRenderer::restore() { mRestoreSaveCount--; flushTranslate(); StatefulBaseRenderer::restore(); mState.restore(); } void DisplayListRenderer::restoreToCount(int saveCount) { mRestoreSaveCount = saveCount; flushTranslate(); StatefulBaseRenderer::restoreToCount(saveCount); mState.restoreToCount(saveCount); } int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, Loading @@ -120,7 +121,7 @@ int DisplayListRenderer::saveLayer(float left, float top, float right, float bot paint = refPaint(paint); addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags)); return StatefulBaseRenderer::save(flags); return mState.save(flags); } void DisplayListRenderer::translate(float dx, float dy, float dz) { Loading @@ -129,50 +130,50 @@ void DisplayListRenderer::translate(float dx, float dy, float dz) { mTranslateX += dx; mTranslateY += dy; flushRestoreToCount(); StatefulBaseRenderer::translate(dx, dy, dz); mState.translate(dx, dy, dz); } void DisplayListRenderer::rotate(float degrees) { addStateOp(new (alloc()) RotateOp(degrees)); StatefulBaseRenderer::rotate(degrees); mState.rotate(degrees); } void DisplayListRenderer::scale(float sx, float sy) { addStateOp(new (alloc()) ScaleOp(sx, sy)); StatefulBaseRenderer::scale(sx, sy); mState.scale(sx, sy); } void DisplayListRenderer::skew(float sx, float sy) { addStateOp(new (alloc()) SkewOp(sx, sy)); StatefulBaseRenderer::skew(sx, sy); mState.skew(sx, sy); } void DisplayListRenderer::setMatrix(const SkMatrix& matrix) { addStateOp(new (alloc()) SetMatrixOp(matrix)); StatefulBaseRenderer::setMatrix(matrix); mState.setMatrix(matrix); } void DisplayListRenderer::concatMatrix(const SkMatrix& matrix) { addStateOp(new (alloc()) ConcatMatrixOp(matrix)); StatefulBaseRenderer::concatMatrix(matrix); mState.concatMatrix(matrix); } bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); return StatefulBaseRenderer::clipRect(left, top, right, bottom, op); return mState.clipRect(left, top, right, bottom, op); } bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) { path = refPath(path); addStateOp(new (alloc()) ClipPathOp(path, op)); return StatefulBaseRenderer::clipPath(path, op); return mState.clipPath(path, op); } bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { region = refRegion(region); addStateOp(new (alloc()) ClipRegionOp(region, op)); return StatefulBaseRenderer::clipRegion(region, op); return mState.clipRegion(region, op); } void DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) { Loading @@ -180,7 +181,7 @@ void DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, in // dirty is an out parameter and should not be recorded, // it matters only when replaying the display list DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *currentTransform()); DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *mState.currentTransform()); addRenderNodeOp(op); } Loading
libs/hwui/DisplayListRenderer.h +29 −3 File changed.Preview size limit exceeded, changes collapsed. Show changes