diff options
Diffstat (limited to 'libs')
59 files changed, 1017 insertions, 972 deletions
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 39f175f..acb8934 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -4635,7 +4635,7 @@ bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue) if (len > 0) { return false; } - if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') { + if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.' && buf[0] != '-' && buf[0] != '+') { return false; } diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp index 09e090d..9dcd3a8 100644 --- a/libs/hwui/AmbientShadow.cpp +++ b/libs/hwui/AmbientShadow.cpp @@ -60,6 +60,7 @@ #include "AmbientShadow.h" #include "ShadowTessellator.h" #include "Vertex.h" +#include "VertexBuffer.h" #include "utils/MathUtils.h" namespace android { diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h index 9660dc0..8eb1048 100644 --- a/libs/hwui/AmbientShadow.h +++ b/libs/hwui/AmbientShadow.h @@ -19,13 +19,13 @@ #define ANDROID_HWUI_AMBIENT_SHADOW_H #include "Debug.h" -#include "OpenGLRenderer.h" #include "Vector.h" -#include "VertexBuffer.h" namespace android { namespace uirenderer { +class VertexBuffer; + /** * AmbientShadow is used to calculate the ambient shadow value around a polygon. */ diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 3e590a9..8cc4d15 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -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 \ @@ -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 \ @@ -62,7 +63,6 @@ ifeq ($(USE_OPENGL_RENDERER),true) SkiaShader.cpp \ Snapshot.cpp \ SpotShadow.cpp \ - StatefulBaseRenderer.cpp \ Stencil.cpp \ TessellationCache.cpp \ Texture.cpp \ diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp index 8bf2107..a1bbc06 100644 --- a/libs/hwui/Animator.cpp +++ b/libs/hwui/Animator.cpp @@ -20,6 +20,7 @@ #include <set> #include "AnimationContext.h" +#include "Interpolator.h" #include "RenderNode.h" #include "RenderProperties.h" diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h index 35a4a09..99f8956 100644 --- a/libs/hwui/Animator.h +++ b/libs/hwui/Animator.h @@ -19,10 +19,8 @@ #include <cutils/compiler.h> #include <utils/RefBase.h> #include <utils/StrongPointer.h> +#include <utils/Timers.h> -#include "CanvasProperty.h" -#include "Interpolator.h" -#include "TreeInfo.h" #include "utils/Macros.h" namespace android { @@ -30,6 +28,9 @@ namespace uirenderer { class AnimationContext; class BaseRenderNodeAnimator; +class CanvasPropertyPrimitive; +class CanvasPropertyPaint; +class Interpolator; class RenderNode; class RenderProperties; diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp index c28fb88..9a4ba21 100644 --- a/libs/hwui/AnimatorManager.cpp +++ b/libs/hwui/AnimatorManager.cpp @@ -17,7 +17,9 @@ #include <algorithm> +#include "Animator.h" #include "AnimationContext.h" +#include "DamageAccumulator.h" #include "RenderNode.h" namespace android { diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h index d03d427..fb75eb8 100644 --- a/libs/hwui/AnimatorManager.h +++ b/libs/hwui/AnimatorManager.h @@ -21,7 +21,6 @@ #include <cutils/compiler.h> #include <utils/StrongPointer.h> -#include "TreeInfo.h" #include "utils/Macros.h" namespace android { @@ -30,6 +29,7 @@ namespace uirenderer { class AnimationHandle; class BaseRenderNodeAnimator; class RenderNode; +class TreeInfo; // Responsible for managing the animators for a single RenderNode class AnimatorManager { diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp index fc86e4f..faec5d2 100644 --- a/libs/hwui/AssetAtlas.cpp +++ b/libs/hwui/AssetAtlas.cpp @@ -18,6 +18,7 @@ #include "AssetAtlas.h" #include "Caches.h" +#include "Image.h" #include <GLES2/gl2ext.h> diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h index 2ec556e..6f72793 100644 --- a/libs/hwui/AssetAtlas.h +++ b/libs/hwui/AssetAtlas.h @@ -27,7 +27,6 @@ #include <SkBitmap.h> -#include "Image.h" #include "Texture.h" #include "UvMapper.h" @@ -35,6 +34,7 @@ namespace android { namespace uirenderer { class Caches; +class Image; /** * An asset atlas holds a collection of framework bitmaps in a single OpenGL diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 952f739..23635fd 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -21,6 +21,7 @@ #include "Caches.h" #include "DisplayListRenderer.h" +#include "GammaFontRenderer.h" #include "Properties.h" #include "LayerRenderer.h" #include "ShadowTessellator.h" diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index e338686..4b8b626 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -31,13 +31,13 @@ #include <cutils/compiler.h> +#include <SkPath.h> + #include "thread/TaskProcessor.h" #include "thread/TaskManager.h" #include "AssetAtlas.h" #include "Extensions.h" -#include "FontRenderer.h" -#include "GammaFontRenderer.h" #include "TextureCache.h" #include "LayerCache.h" #include "RenderBufferCache.h" @@ -55,6 +55,8 @@ namespace android { namespace uirenderer { +class GammaFontRenderer; + /////////////////////////////////////////////////////////////////////////////// // Globals /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/CanvasState.cpp index 88d6f68..20cc17e 100644 --- a/libs/hwui/StatefulBaseRenderer.cpp +++ b/libs/hwui/CanvasState.cpp @@ -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. @@ -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; @@ -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) { @@ -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); } @@ -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(); @@ -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); @@ -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 @@ -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); } @@ -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 { @@ -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; @@ -288,5 +281,5 @@ bool StatefulBaseRenderer::quickRejectConservative(float left, float top, return false; } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/CanvasState.h b/libs/hwui/CanvasState.h new file mode 100644 index 0000000..6883d0a --- /dev/null +++ b/libs/hwui/CanvasState.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HWUI_CANVAS_STATE_H +#define ANDROID_HWUI_CANVAS_STATE_H + +#include <SkMatrix.h> +#include <SkPath.h> +#include <SkRegion.h> + +#include "Snapshot.h" + +namespace android { +namespace uirenderer { + +/** + * 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 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 CanvasState, so that not only will querying operations work (getClip/Matrix), but so + * that quickRejection can also be used. + */ + +class ANDROID_API CanvasState { +public: + CanvasState(CanvasStateClient& renderer); + ~CanvasState(); + + /** + * Initializes the first snapshot, computing the projection matrix, + * and stores the dimensions of the render target. + */ + void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom, + const Vector3& lightCenter); + + void setViewport(int width, int height); + + bool hasRectToRectTransform() const { + return CC_LIKELY(currentTransform()->rectToRect()); + } + + // Save (layer) + 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 + 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); + + void setMatrix(const SkMatrix& matrix); + void setMatrix(const Matrix4& matrix); // internal only convenience method + void concatMatrix(const SkMatrix& matrix); + void concatMatrix(const Matrix4& matrix); // internal only convenience method + + // Clip + 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; + + 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); + + bool isCurrentClipSimple() const { + return currentSnapshot()->clipRegion->isEmpty(); + } + + /** + * 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); + + /** + * 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. + */ + bool calculateQuickRejectForScissor(float left, float top, float right, float bottom, + bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const; + + 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(); } + +private: + /// No default constructor - must supply a CanvasStateClient (mCanvas). + CanvasState(); + + /// indicates that the clip has been changed since the last time it was consumed + bool mDirtyClip; + + /// Dimensions of the drawing surface + int mWidth, mHeight; + + /// Number of saved states + int mSaveCount; + + /// Base state + sp<Snapshot> mFirstSnapshot; + + /// Host providing callbacks + CanvasStateClient& mCanvas; + + /// Current state + sp<Snapshot> mSnapshot; + +}; // class CanvasState + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_CANVAS_STATE_H diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp index e2f8bc4..ea1d714 100644 --- a/libs/hwui/DeferredDisplayList.cpp +++ b/libs/hwui/DeferredDisplayList.cpp @@ -52,7 +52,7 @@ namespace uirenderer { class Batch { public: - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) = 0; + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) = 0; virtual ~Batch() {} virtual bool purelyDrawBatch() { return false; } virtual bool coversBounds(const Rect& bounds) { return false; } @@ -91,11 +91,10 @@ public: return false; } - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { DEFER_LOGD("%d replaying DrawBatch %p, with %d ops (batch id %x, merge id %p)", index, this, mOps.size(), getBatchId(), getMergeId()); - status_t status = DrawGlInfo::kStatusDone; DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); for (unsigned int i = 0; i < mOps.size(); i++) { DrawOp* op = mOps[i].op; @@ -106,7 +105,7 @@ public: renderer.eventMark(op->name()); #endif logBuffer.writeCommand(0, op->name()); - status |= op->applyDraw(renderer, dirty); + op->applyDraw(renderer, dirty); #if DEBUG_MERGE_BEHAVIOR const Rect& bounds = state->mBounds; @@ -118,7 +117,6 @@ public: batchColor); #endif } - return status; } virtual bool purelyDrawBatch() { return true; } @@ -235,26 +233,6 @@ public: return false; } - /* Draw Modifiers compatibility check - * - * Shadows are ignored, as only text uses them, and in that case they are drawn - * per-DrawTextOp, before the unified text draw. Because of this, it's always safe to merge - * text UNLESS a later draw's shadow should overlays a previous draw's text. This is covered - * above with the intersection check. - * - * OverrideLayerAlpha is also ignored, as it's only used for drawing layers, which are never - * merged. - * - * These ignore cases prevent us from simply memcmp'ing the drawModifiers - */ - const DrawModifiers& lhsMod = lhs->mDrawModifiers; - const DrawModifiers& rhsMod = rhs->mDrawModifiers; - - // Draw filter testing expects bit fields to be clear if filter not set. - if (lhsMod.mHasDrawFilter != rhsMod.mHasDrawFilter) return false; - if (lhsMod.mPaintFilterClearBits != rhsMod.mPaintFilterClearBits) return false; - if (lhsMod.mPaintFilterSetBits != rhsMod.mPaintFilterSetBits) return false; - return true; } @@ -269,12 +247,13 @@ public: if (newClipSideFlags & kClipSide_Bottom) mClipRect.bottom = state->mClip.bottom; } - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { DEFER_LOGD("%d replaying MergingDrawBatch %p, with %d ops," " clip flags %x (batch id %x, merge id %p)", index, this, mOps.size(), mClipSideFlags, getBatchId(), getMergeId()); if (mOps.size() == 1) { - return DrawBatch::replay(renderer, dirty, -1); + DrawBatch::replay(renderer, dirty, -1); + return; } // clipping in the merged case is done ahead of time since all ops share the clip (if any) @@ -289,13 +268,12 @@ public: renderer.eventMark("multiDraw"); renderer.eventMark(op->name()); #endif - status_t status = op->multiDraw(renderer, dirty, mOps, mBounds); + op->multiDraw(renderer, dirty, mOps, mBounds); #if DEBUG_MERGE_BEHAVIOR renderer.drawScreenSpaceColorRect(mBounds.left, mBounds.top, mBounds.right, mBounds.bottom, DEBUG_COLOR_MERGEDBATCH); #endif - return status; } private: @@ -313,7 +291,7 @@ public: // creates a single operation batch StateOpBatch(const StateOp* op, const DeferredDisplayState* state) : mOp(op), mState(state) {} - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { DEFER_LOGD("replaying state op batch %p", this); renderer.restoreDisplayState(*mState); @@ -322,7 +300,6 @@ public: // renderer.restoreToCount directly int saveCount = -1; mOp->applyState(renderer, saveCount); - return DrawGlInfo::kStatusDone; } private: @@ -335,12 +312,11 @@ public: RestoreToCountBatch(const StateOp* op, const DeferredDisplayState* state, int restoreCount) : mState(state), mRestoreCount(restoreCount) {} - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { DEFER_LOGD("batch %p restoring to count %d", this, mRestoreCount); renderer.restoreDisplayState(*mState); renderer.restoreToCount(mRestoreCount); - return DrawGlInfo::kStatusDone; } private: @@ -358,9 +334,8 @@ private: #if DEBUG_MERGE_BEHAVIOR class BarrierDebugBatch : public Batch { - virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) { + virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) { renderer.drawScreenSpaceColorRect(0, 0, 10000, 10000, DEBUG_COLOR_BARRIER); - return DrawGlInfo::kStatusDrew; } }; #endif @@ -647,26 +622,22 @@ void DeferredDisplayList::storeRestoreToCountBarrier(OpenGLRenderer& renderer, S // Replay / flush ///////////////////////////////////////////////////////////////////////////////// -static status_t replayBatchList(const Vector<Batch*>& batchList, +static void replayBatchList(const Vector<Batch*>& batchList, OpenGLRenderer& renderer, Rect& dirty) { - status_t status = DrawGlInfo::kStatusDone; for (unsigned int i = 0; i < batchList.size(); i++) { if (batchList[i]) { - status |= batchList[i]->replay(renderer, dirty, i); + batchList[i]->replay(renderer, dirty, i); } } DEFER_LOGD("--flushed, drew %d batches", batchList.size()); - return status; } -status_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) { +void DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) { ATRACE_NAME("flush drawing commands"); Caches::getInstance().fontRenderer->endPrecaching(); - status_t status = DrawGlInfo::kStatusDone; - - if (isEmpty()) return status; // nothing to flush + if (isEmpty()) return; // nothing to flush renderer.restoreToCount(1); DEFER_LOGD("--flushing"); @@ -684,14 +655,13 @@ status_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) { // NOTE: depth of the save stack at this point, before playback, should be reflected in // FLUSH_SAVE_STACK_DEPTH, so that save/restores match up correctly - status |= replayBatchList(mBatches, renderer, dirty); + replayBatchList(mBatches, renderer, dirty); renderer.restoreToCount(1); renderer.setDrawModifiers(restoreDrawModifiers); DEFER_LOGD("--flush complete, returning %x", status); clear(); - return status; } void DeferredDisplayList::discardDrawingBatches(const unsigned int maxIndex) { diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h index 9d02382..fe70ec2 100644 --- a/libs/hwui/DeferredDisplayList.h +++ b/libs/hwui/DeferredDisplayList.h @@ -106,7 +106,7 @@ public: * Plays back all of the draw ops recorded into batches to the renderer. * Adjusts the state of the renderer as necessary, and restores it when complete */ - status_t flush(OpenGLRenderer& renderer, Rect& dirty); + void flush(OpenGLRenderer& renderer, Rect& dirty); void addClip(OpenGLRenderer& renderer, ClipOp* op); void addSaveLayer(OpenGLRenderer& renderer, SaveLayerOp* op, int newSaveCount); diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 84411ed..61efafe 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -24,7 +24,6 @@ #include "Layer.h" #include "Rect.h" -#include "RenderNode.h" #include "renderthread/RenderThread.h" namespace android { @@ -39,7 +38,7 @@ public: ANDROID_API DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer); ANDROID_API ~DeferredLayerUpdater(); - ANDROID_API bool setSize(uint32_t width, uint32_t height) { + ANDROID_API bool setSize(int width, int height) { if (mWidth != width || mHeight != height) { mWidth = width; mHeight = height; @@ -84,8 +83,8 @@ public: private: // Generic properties - uint32_t mWidth; - uint32_t mHeight; + int mWidth; + int mHeight; bool mBlend; SkColorFilter* mColorFilter; int mAlpha; diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index e15adf3..43dabdb 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -38,8 +38,9 @@ #include <androidfw/ResourceTypes.h> #include "Debug.h" -#include "Matrix.h" +#include "CanvasProperty.h" #include "DeferredDisplayList.h" +#include "Matrix.h" #include "RenderProperties.h" class SkBitmap; @@ -103,10 +104,9 @@ class ReplayStateStruct : public PlaybackStateStruct { public: ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags) : PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator), - mDirty(dirty), mDrawGlStatus(DrawGlInfo::kStatusDone) {} + mDirty(dirty) {} Rect& mDirty; - status_t mDrawGlStatus; LinearAllocator mReplayAllocator; }; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index d78c1cb..7627163 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -32,6 +32,9 @@ #include "AssetAtlas.h" #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" +#include "GammaFontRenderer.h" +#include "Patch.h" +#include "RenderNode.h" #include "UvMapper.h" #include "utils/LinearAllocator.h" @@ -132,10 +135,10 @@ public: return; } - replayStruct.mDrawGlStatus |= applyDraw(replayStruct.mRenderer, replayStruct.mDirty); + applyDraw(replayStruct.mRenderer, replayStruct.mDirty); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0; + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0; /** * Draw multiple instances of an operation, must be overidden for operations that merge @@ -144,14 +147,12 @@ public: * and pure translation transformations. Other guarantees of similarity should be enforced by * reducing which operations are tagged as mergeable. */ - virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, const Vector<OpStatePair>& ops, const Rect& bounds) { - status_t status = DrawGlInfo::kStatusDone; for (unsigned int i = 0; i < ops.size(); i++) { renderer.restoreDisplayState(*(ops[i].state), true); - status |= ops[i].op->applyDraw(renderer, dirty); + ops[i].op->applyDraw(renderer, dirty); } - return status; } /** @@ -198,10 +199,6 @@ public: } protected: - const SkPaint* getPaint(OpenGLRenderer& renderer) { - return renderer.filterPaint(mPaint); - } - // Helper method for determining op opaqueness. Assumes op fills its bounds in local // coordinates, and that paint's alpha is used inline bool isOpaqueOverBounds(const DeferredDisplayState& state) { @@ -231,7 +228,7 @@ protected: } - const SkPaint* mPaint; // should be accessed via getPaint() when applying + const SkPaint* mPaint; bool mQuickRejected; }; @@ -605,39 +602,6 @@ private: const SkRegion* mRegion; }; -class ResetPaintFilterOp : public StateOp { -public: - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.resetPaintFilter(); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOGS("ResetPaintFilter"); - } - - virtual const char* name() { return "ResetPaintFilter"; } -}; - -class SetupPaintFilterOp : public StateOp { -public: - SetupPaintFilterOp(int clearBits, int setBits) - : mClearBits(clearBits), mSetBits(setBits) {} - - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.setupPaintFilter(mClearBits, mSetBits); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits); - } - - virtual const char* name() { return "SetupPaintFilter"; } - -private: - int mClearBits; - int mSetBits; -}; - /////////////////////////////////////////////////////////////////////////////// // DRAW OPERATIONS - these are operations that can draw to the canvas's device /////////////////////////////////////////////////////////////////////////////// @@ -655,8 +619,8 @@ public: } } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmap(mBitmap, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawBitmap(mBitmap, mPaint); } AssetAtlas::Entry* getAtlasEntry() { @@ -678,7 +642,7 @@ public: * for each bitmap in the batch. This method is also responsible for dirtying * the current layer, if any. */ - virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, const Vector<OpStatePair>& ops, const Rect& bounds) { const DeferredDisplayState& firstState = *(ops[0].state); renderer.restoreDisplayState(firstState, true); // restore all but the clip @@ -715,7 +679,7 @@ public: } } - return renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0], + renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0], pureTranslate, bounds, mPaint); } @@ -758,10 +722,10 @@ public: : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint), mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, - getPaint(renderer)); + mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -786,8 +750,8 @@ public: DrawBitmapDataOp(const SkBitmap* bitmap, const SkPaint* paint) : DrawBitmapOp(bitmap, paint) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmapData(mBitmap, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawBitmapData(mBitmap, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -810,9 +774,9 @@ public: mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight), mVertices(vertices), mColors(colors) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, - mVertices, mColors, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, + mVertices, mColors, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -871,7 +835,7 @@ public: * and transforming the vertices of each 9-patch in the batch. This method * is also responsible for dirtying the current layer, if any. */ - virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, const Vector<OpStatePair>& ops, const Rect& bounds) { const DeferredDisplayState& firstState = *(ops[0].state); renderer.restoreDisplayState(firstState, true); // restore all but the clip @@ -941,16 +905,16 @@ public: indexCount += opMesh->indexCount; } - return renderer.drawPatches(mBitmap, getAtlasEntry(), - &vertices[0], indexCount, getPaint(renderer)); + renderer.drawPatches(mBitmap, getAtlasEntry(), + &vertices[0], indexCount, mPaint); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { // We're not calling the public variant of drawPatch() here // This method won't perform the quickReject() since we've already done it at this point - return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(), + renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(), mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, - getPaint(renderer)); + mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -985,8 +949,8 @@ public: DrawColorOp(int color, SkXfermode::Mode mode) : DrawOp(NULL), mColor(color), mMode(mode) {}; - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawColor(mColor, mMode); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawColor(mColor, mMode); } virtual void output(int level, uint32_t logFlags) const { @@ -1032,9 +996,9 @@ public: DrawRectOp(float left, float top, float right, float bottom, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawRect(mLocalBounds.left, mLocalBounds.top, - mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawRect(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1057,8 +1021,8 @@ public: : DrawBoundedOp(rects, count, paint), mRects(rects), mCount(count) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawRects(mRects, mCount, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawRects(mRects, mCount, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1083,9 +1047,9 @@ public: float rx, float ry, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, - mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1115,9 +1079,9 @@ public: : DrawOp(paint), mLeft(left), mTop(top), mRight(right), mBottom(bottom), mRx(rx), mRy(ry) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom, - *mRx, *mRy, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom, + *mRx, *mRy, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1142,8 +1106,8 @@ public: : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint), mX(x), mY(y), mRadius(radius) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawCircle(mX, mY, mRadius, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1163,8 +1127,8 @@ public: DrawCirclePropsOp(float* x, float* y, float* radius, const SkPaint* paint) : DrawOp(paint), mX(x), mY(y), mRadius(radius) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawCircle(*mX, *mY, *mRadius, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawCircle(*mX, *mY, *mRadius, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1184,9 +1148,9 @@ public: DrawOvalOp(float left, float top, float right, float bottom, const SkPaint* paint) : DrawStrokableOp(left, top, right, bottom, paint) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawOval(mLocalBounds.left, mLocalBounds.top, - mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawOval(mLocalBounds.left, mLocalBounds.top, + mLocalBounds.right, mLocalBounds.bottom, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1203,10 +1167,10 @@ public: : DrawStrokableOp(left, top, right, bottom, paint), mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawArc(mLocalBounds.left, mLocalBounds.top, + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawArc(mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, - mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer)); + mStartAngle, mSweepAngle, mUseCenter, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1234,14 +1198,13 @@ public: mLocalBounds.set(left, top, left + width, top + height); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawPath(mPath, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawPath(mPath, mPaint); } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - const SkPaint* paint = getPaint(renderer); - renderer.getCaches().pathCache.precache(mPath, paint); + renderer.getCaches().pathCache.precache(mPath, mPaint); deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture; } @@ -1264,8 +1227,8 @@ public: mLocalBounds.outset(strokeWidthOutset()); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawLines(mPoints, mCount, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawLines(mPoints, mCount, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1291,8 +1254,8 @@ public: DrawPointsOp(const float* points, int count, const SkPaint* paint) : DrawLinesOp(points, count, paint) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawPoints(mPoints, mCount, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawPoints(mPoints, mCount, mPaint); } virtual void output(int level, uint32_t logFlags) const { @@ -1317,9 +1280,8 @@ public: virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - const SkPaint* paint = getPaint(renderer); - FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); - fontRenderer.precache(paint, mText, mCount, SkMatrix::I()); + FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint); + fontRenderer.precache(mPaint, mText, mCount, SkMatrix::I()); deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ? DeferredDisplayList::kOpBatch_Text : @@ -1341,9 +1303,9 @@ public: /* TODO: inherit from DrawBounded and init mLocalBounds */ } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, - mHOffset, mVOffset, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, + mHOffset, mVOffset, mPaint); } virtual const char* name() { return "DrawTextOnPath"; } @@ -1362,8 +1324,8 @@ public: /* TODO: inherit from DrawBounded and init mLocalBounds */ } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer)); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawPosText(mText, mBytesCount, mCount, mPositions, mPaint); } virtual const char* name() { return "DrawPosText"; } @@ -1383,12 +1345,11 @@ public: virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { - const SkPaint* paint = getPaint(renderer); - FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); + FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint); SkMatrix transform; renderer.findBestFontTransform(state.mMatrix, &transform); if (mPrecacheTransform != transform) { - fontRenderer.precache(paint, mText, mCount, transform); + fontRenderer.precache(mPaint, mText, mCount, transform); mPrecacheTransform = transform; } deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ? @@ -1406,16 +1367,15 @@ public: && OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode; } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { Rect bounds; getLocalBounds(bounds); - return renderer.drawText(mText, mBytesCount, mCount, mX, mY, - mPositions, getPaint(renderer), mTotalAdvance, bounds); + renderer.drawText(mText, mBytesCount, mCount, mX, mY, + mPositions, mPaint, mTotalAdvance, bounds); } - virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty, + virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, const Vector<OpStatePair>& ops, const Rect& bounds) { - status_t status = DrawGlInfo::kStatusDone; for (unsigned int i = 0; i < ops.size(); i++) { const DeferredDisplayState& state = *(ops[i].state); DrawOpMode drawOpMode = (i == ops.size() - 1) ? kDrawOpMode_Flush : kDrawOpMode_Defer; @@ -1424,11 +1384,10 @@ public: DrawTextOp& op = *((DrawTextOp*)ops[i].op); // quickReject() will not occure in drawText() so we can use mLocalBounds // directly, we do not need to account for shadow by calling getLocalBounds() - status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY, - op.mPositions, op.getPaint(renderer), op.mTotalAdvance, op.mLocalBounds, + renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY, + op.mPositions, op.mPaint, op.mTotalAdvance, op.mLocalBounds, drawOpMode); } - return status; } virtual void output(int level, uint32_t logFlags) const { @@ -1457,11 +1416,10 @@ public: DrawFunctorOp(Functor* functor) : DrawOp(NULL), mFunctor(functor) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { renderer.startMark("GL functor"); - status_t ret = renderer.callDrawGLFunction(mFunctor, dirty); + renderer.callDrawGLFunction(mFunctor, dirty); renderer.endMark(); - return ret; } virtual void output(int level, uint32_t logFlags) const { @@ -1496,9 +1454,8 @@ public: } } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { LOG_ALWAYS_FATAL("should not be called, because replay() is overridden"); - return 0; } virtual void output(int level, uint32_t logFlags) const { @@ -1557,7 +1514,7 @@ public: &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius()); } - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { TessellationCache::vertexBuffer_pair_t buffers; Matrix4 drawTransform(*(renderer.currentTransform())); renderer.getCaches().tessellationCache.getShadowBuffers(&drawTransform, @@ -1565,7 +1522,7 @@ public: &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius(), buffers); - return renderer.drawShadow(mCasterAlpha, buffers.first, buffers.second); + renderer.drawShadow(mCasterAlpha, buffers.first, buffers.second); } virtual void output(int level, uint32_t logFlags) const { @@ -1588,8 +1545,8 @@ public: DrawLayerOp(Layer* layer, float x, float y) : DrawOp(NULL), mLayer(layer), mX(x), mY(y) {} - virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return renderer.drawLayer(mLayer, mX, mY); + virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + renderer.drawLayer(mLayer, mX, mY); } virtual void output(int level, uint32_t logFlags) const { diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index c2cb76e..8887aa7 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -33,7 +33,8 @@ namespace android { namespace uirenderer { DisplayListRenderer::DisplayListRenderer() - : mResourceCache(ResourceCache::getInstance()) + : mState(*this) + , mResourceCache(ResourceCache::getInstance()) , mDisplayListData(NULL) , mTranslateX(0.0f) , mTranslateY(0.0f) @@ -60,25 +61,24 @@ DisplayListData* DisplayListRenderer::finishRecording() { return data; } -status_t DisplayListRenderer::prepareDirty(float left, float top, +void DisplayListRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { LOG_ALWAYS_FATAL_IF(mDisplayListData, "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; - - return DrawGlInfo::kStatusDone; // No invalidate needed at record-time } -void DisplayListRenderer::finish() { +bool DisplayListRenderer::finish() { flushRestoreToCount(); flushTranslate(); + return false; } void DisplayListRenderer::interrupt() { @@ -87,16 +87,15 @@ void DisplayListRenderer::interrupt() { void DisplayListRenderer::resume() { } -status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { +void DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { // Ignore dirty during recording, it matters only when we replay addDrawOp(new (alloc()) DrawFunctorOp(functor)); mDisplayListData->functors.add(functor); - return DrawGlInfo::kStatusDone; // No invalidate needed at record-time } int DisplayListRenderer::save(int flags) { addStateOp(new (alloc()) SaveOp(flags)); - return StatefulBaseRenderer::save(flags); + return mState.save(flags); } void DisplayListRenderer::restore() { @@ -107,13 +106,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, @@ -123,7 +122,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) { @@ -132,80 +131,76 @@ 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); } -status_t DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) { +void DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) { LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode"); // 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); - - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) { +void DisplayListRenderer::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) { // We ref the DeferredLayerUpdater due to its thread-safe ref-counting // semantics. mDisplayListData->ref(layerHandle); addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer(), x, y)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { +void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { bitmap = refBitmap(bitmap); paint = refPaint(paint); addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, +void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { if (srcLeft == 0 && srcTop == 0 @@ -225,18 +220,16 @@ status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, paint)); } - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { +void DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { bitmap = refBitmapData(bitmap); paint = refPaint(paint); addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, +void DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) { int vertexCount = (meshWidth + 1) * (meshHeight + 1); bitmap = refBitmap(bitmap); @@ -246,39 +239,34 @@ status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWid addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, vertices, colors, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, +void DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) { bitmap = refBitmap(bitmap); patch = refPatch(patch); paint = refPaint(paint); addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { +void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { addDrawOp(new (alloc()) DrawColorOp(color, mode)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, +void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, +void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRoundRect( +void DisplayListRenderer::drawRoundRect( CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, @@ -292,16 +280,14 @@ status_t DisplayListRenderer::drawRoundRect( mDisplayListData->ref(paint); addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value, &right->value, &bottom->value, &rx->value, &ry->value, &paint->value)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) { +void DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, +void DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { mDisplayListData->ref(x); mDisplayListData->ref(y); @@ -309,55 +295,49 @@ status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPrope mDisplayListData->ref(paint); addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value, &radius->value, &paint->value)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom, +void DisplayListRenderer::drawOval(float left, float top, float right, float bottom, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom, +void DisplayListRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) { if (fabs(sweepAngle) >= 360.0f) { - return drawOval(left, top, right, bottom, paint); + drawOval(left, top, right, bottom, paint); + } else { + paint = refPaint(paint); + addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, + startAngle, sweepAngle, useCenter, paint)); } - - paint = refPaint(paint); - addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, - startAngle, sweepAngle, useCenter, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) { +void DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) { path = refPath(path); paint = refPaint(paint); addDrawOp(new (alloc()) DrawPathOp(path, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) { +void DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) { points = refBuffer<float>(points, count); paint = refPaint(paint); addDrawOp(new (alloc()) DrawLinesOp(points, count, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { +void DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { points = refBuffer<float>(points, count); paint = refPaint(paint); addDrawOp(new (alloc()) DrawPointsOp(points, count, paint)); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, +void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { - if (!text || count <= 0) return DrawGlInfo::kStatusDone; + if (!text || count <= 0) return; text = refText(text, bytesCount); path = refPath(path); @@ -366,12 +346,11 @@ status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, i DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path, hOffset, vOffset, paint); addDrawOp(op); - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, +void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint) { - if (!text || count <= 0) return DrawGlInfo::kStatusDone; + if (!text || count <= 0) return; text = refText(text, bytesCount); positions = refBuffer<float>(positions, count * 2); @@ -379,7 +358,6 @@ status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint); addDrawOp(op); - return DrawGlInfo::kStatusDone; } static void simplifyPaint(int color, SkPaint* paint) { @@ -392,11 +370,11 @@ static void simplifyPaint(int color, SkPaint* paint) { paint->setLooper(NULL); } -status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, +void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { - if (!text || count <= 0 || paintWillNotDrawText(*paint)) return DrawGlInfo::kStatusDone; + if (!text || count <= 0 || paintWillNotDrawText(*paint)) return; text = refText(text, bytesCount); positions = refBuffer<float>(positions, count * 2); @@ -428,24 +406,18 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou x, y, positions, paint, totalAdvance, bounds); addDrawOp(op); } - return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { - if (count <= 0) return DrawGlInfo::kStatusDone; +void DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { + if (count <= 0) return; rects = refBuffer<float>(rects, count); paint = refPaint(paint); addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint)); - return DrawGlInfo::kStatusDone; -} - -void DisplayListRenderer::resetPaintFilter() { - addStateOp(new (alloc()) ResetPaintFilterOp()); } -void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) { - addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits)); +void DisplayListRenderer::setDrawFilter(SkDrawFilter* filter) { + mDrawFilter.reset(filter); } void DisplayListRenderer::insertReorderBarrier(bool enableReorder) { diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 2cc2be3..6646da7 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -17,13 +17,19 @@ #ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H #define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H +#include <SkDrawFilter.h> #include <SkMatrix.h> #include <SkPaint.h> #include <SkPath.h> +#include <SkRegion.h> +#include <SkTLazy.h> #include <cutils/compiler.h> +#include "CanvasState.h" +#include "DisplayList.h" #include "DisplayListLogBuffer.h" #include "RenderNode.h" +#include "Renderer.h" #include "ResourceCache.h" namespace android { @@ -48,13 +54,15 @@ class DeferredDisplayList; class DeferredLayerUpdater; class DisplayListRenderer; class DisplayListOp; +class DisplayListRenderer; class DrawOp; +class RenderNode; class StateOp; /** * Records drawing commands in a display list for later playback into an OpenGLRenderer. */ -class ANDROID_API DisplayListRenderer: public StatefulBaseRenderer { +class ANDROID_API DisplayListRenderer: public Renderer, public CanvasStateClient { public: DisplayListRenderer(); virtual ~DisplayListRenderer(); @@ -66,15 +74,21 @@ public: // ---------------------------------------------------------------------------- // Frame state operations // ---------------------------------------------------------------------------- - virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); - virtual void finish(); + virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque); + virtual void prepare(bool opaque) { + prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque); + } + virtual bool finish(); virtual void interrupt(); virtual void resume(); // ---------------------------------------------------------------------------- // Canvas state operations // ---------------------------------------------------------------------------- + virtual void setViewport(int width, int height) { mState.setViewport(width, height); } + // Save (layer) + virtual int getSaveCount() const { return mState.getSaveCount(); } virtual int save(int flags); virtual void restore(); virtual void restoreToCount(int saveCount); @@ -82,6 +96,8 @@ public: const SkPaint* paint, int flags); // Matrix + virtual void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); } + virtual void translate(float dx, float dy, float dz = 0.0f); virtual void rotate(float degrees); virtual void scale(float sx, float sy); @@ -95,73 +111,88 @@ public: virtual bool clipPath(const SkPath* path, SkRegion::Op op); virtual bool clipRegion(const SkRegion* region, SkRegion::Op op); - // Misc - should be implemented with SkPaint inspection - virtual void resetPaintFilter(); - virtual void setupPaintFilter(int clearBits, int setBits); + // Misc + virtual void setDrawFilter(SkDrawFilter* filter); + virtual const Rect& getLocalClipBounds() const { return mState.getLocalClipBounds(); } + const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); } + virtual bool quickRejectConservative(float left, float top, float right, float bottom) const { + return mState.quickRejectConservative(left, top, right, bottom); + } bool isCurrentTransformSimple() { - return currentTransform()->isSimple(); + return mState.currentTransform()->isSimple(); } // ---------------------------------------------------------------------------- // Canvas draw operations // ---------------------------------------------------------------------------- - virtual status_t drawColor(int color, SkXfermode::Mode mode); + virtual void drawColor(int color, SkXfermode::Mode mode); // Bitmap-based - virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); - virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, + virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); + virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint); - virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint); - virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, + virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint); + virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint); - virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, + virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint); // Shapes - virtual status_t drawRect(float left, float top, float right, float bottom, + virtual void drawRect(float left, float top, float right, float bottom, const SkPaint* paint); - virtual status_t drawRects(const float* rects, int count, const SkPaint* paint); - virtual status_t drawRoundRect(float left, float top, float right, float bottom, + virtual void drawRects(const float* rects, int count, const SkPaint* paint); + virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* paint); - virtual status_t drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, + virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, CanvasPropertyPaint* paint); - virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint); - virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, + virtual void drawCircle(float x, float y, float radius, const SkPaint* paint); + virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint); - virtual status_t drawOval(float left, float top, float right, float bottom, + virtual void drawOval(float left, float top, float right, float bottom, const SkPaint* paint); - virtual status_t drawArc(float left, float top, float right, float bottom, + virtual void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint); - virtual status_t drawPath(const SkPath* path, const SkPaint* paint); - virtual status_t drawLines(const float* points, int count, const SkPaint* paint); - virtual status_t drawPoints(const float* points, int count, const SkPaint* paint); + virtual void drawPath(const SkPath* path, const SkPaint* paint); + virtual void drawLines(const float* points, int count, const SkPaint* paint); + virtual void drawPoints(const float* points, int count, const SkPaint* paint); // Text - virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, + virtual void drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode = kDrawOpMode_Immediate); - virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, + virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint); - virtual status_t drawPosText(const char* text, int bytesCount, int count, + virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint); // ---------------------------------------------------------------------------- // Canvas draw operations - special // ---------------------------------------------------------------------------- - virtual status_t drawLayer(DeferredLayerUpdater* layerHandle, float x, float y); - virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags); + virtual void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y); + virtual void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags); // TODO: rename for consistency - virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty); + virtual void callDrawGLFunction(Functor* functor, Rect& dirty); void setHighContrastText(bool highContrastText) { mHighContrastText = highContrastText; } + +// ---------------------------------------------------------------------------- +// CanvasState callbacks +// ---------------------------------------------------------------------------- + virtual void onViewportInitialized() { } + virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) { } + virtual GLuint onGetTargetFbo() const { return -1; } + private: + + CanvasState mState; + enum DeferredBarrierType { kBarrier_None, kBarrier_InOrder, @@ -220,35 +251,34 @@ private: inline const SkPaint* refPaint(const SkPaint* paint) { if (!paint) return NULL; - const SkPaint* paintCopy = mPaintMap.valueFor(paint); - if (paintCopy == NULL - || paintCopy->getGenerationID() != paint->getGenerationID() - // We can't compare shader pointers because that will always - // change as we do partial copying via wrapping. However, if the - // shader changes the paint generationID will have changed and - // so we don't hit this comparison anyway - || !(paint->getShader() && paintCopy->getShader() - && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) { - paintCopy = copyPaint(paint); + // If there is a draw filter apply it here and store the modified paint + // so that we don't need to modify the paint every time we access it. + SkTLazy<SkPaint> filteredPaint; + if (mDrawFilter.get()) { + paint = filteredPaint.init(); + mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type); + } + + // compute the hash key for the paint and check the cache. + const uint32_t key = paint->getHash(); + const SkPaint* cachedPaint = mPaintMap.valueFor(key); + // In the unlikely event that 2 unique paints have the same hash we do a + // object equality check to ensure we don't erroneously dedup them. + if (cachedPaint == NULL || *cachedPaint != *paint) { + cachedPaint = new SkPaint(*paint); // replaceValueFor() performs an add if the entry doesn't exist - mPaintMap.replaceValueFor(paint, paintCopy); + mPaintMap.replaceValueFor(key, cachedPaint); + mDisplayListData->paints.add(cachedPaint); } - return paintCopy; + return cachedPaint; } inline SkPaint* copyPaint(const SkPaint* paint) { if (!paint) return NULL; SkPaint* paintCopy = new SkPaint(*paint); - if (paint->getShader()) { - SkShader* shaderCopy = SkShader::CreateLocalMatrixShader( - paint->getShader(), paint->getShader()->getLocalMatrix()); - paintCopy->setShader(shaderCopy); - paintCopy->setGenerationID(paint->getGenerationID()); - shaderCopy->setGenerationID(paint->getShader()->getGenerationID()); - shaderCopy->unref(); - } mDisplayListData->paints.add(paintCopy); + return paintCopy; } @@ -291,7 +321,7 @@ private: return patch; } - DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap; + DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap; DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap; DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap; @@ -306,6 +336,8 @@ private: int mRestoreSaveCount; + SkAutoTUnref<SkDrawFilter> mDrawFilter; + friend class RenderNode; }; // class DisplayListRenderer diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h index 546236b..092ebf2 100644 --- a/libs/hwui/Dither.h +++ b/libs/hwui/Dither.h @@ -19,12 +19,11 @@ #include <GLES3/gl3.h> -#include "Program.h" - namespace android { namespace uirenderer { class Caches; +class Program; // Must be a power of two #define DITHER_KERNEL_SIZE 4 diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index 5c96c6b..e11128c 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -31,8 +31,6 @@ #include "font/CachedGlyphInfo.h" #include "font/Font.h" #include "utils/SortedList.h" -#include "Matrix.h" -#include "Properties.h" #ifdef ANDROID_ENABLE_RENDERSCRIPT #include "RenderScript.h" diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h index 6a783b1..c94b6f0 100644 --- a/libs/hwui/GradientCache.h +++ b/libs/hwui/GradientCache.h @@ -25,11 +25,11 @@ #include <utils/Mutex.h> #include <utils/Vector.h> -#include "Texture.h" - namespace android { namespace uirenderer { +class Texture; + struct GradientCacheEntry { GradientCacheEntry() { count = 0; diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 2d6a727..3b909d5 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -20,6 +20,7 @@ #include <cutils/compiler.h> #include <sys/types.h> #include <utils/StrongPointer.h> +#include <utils/RefBase.h> #include <GLES2/gl2.h> diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index 394c647..268b9da 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -43,7 +43,7 @@ LayerRenderer::LayerRenderer(RenderState& renderState, Layer* layer) LayerRenderer::~LayerRenderer() { } -status_t LayerRenderer::prepareDirty(float left, float top, float right, float bottom, +void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo()); @@ -64,25 +64,23 @@ status_t LayerRenderer::prepareDirty(float left, float top, float right, float b } mLayer->clipRect.set(dirty); - return OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque); + OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque); } -status_t LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) { +void LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) { if (mLayer->isDirty()) { getCaches().disableScissor(); glClear(GL_COLOR_BUFFER_BIT); getCaches().resetScissor(); mLayer->setDirty(false); - - return DrawGlInfo::kStatusDone; + } else { + OpenGLRenderer::clear(left, top, right, bottom, opaque); } - - return OpenGLRenderer::clear(left, top, right, bottom, opaque); } -void LayerRenderer::finish() { - OpenGLRenderer::finish(); +bool LayerRenderer::finish() { + bool retval = OpenGLRenderer::finish(); generateMesh(); @@ -90,9 +88,10 @@ void LayerRenderer::finish() { // No need to unbind our FBO, this will be taken care of by the caller // who will invoke OpenGLRenderer::resume() + return retval; } -GLuint LayerRenderer::getTargetFbo() const { +GLuint LayerRenderer::onGetTargetFbo() const { return mLayer->getFbo(); } @@ -117,7 +116,7 @@ void LayerRenderer::ensureStencilBuffer() { /////////////////////////////////////////////////////////////////////////////// Region* LayerRenderer::getRegion() const { - if (currentSnapshot()->flags & Snapshot::kFlagFboTarget) { + if (mState.currentFlags() & Snapshot::kFlagFboTarget) { return OpenGLRenderer::getRegion(); } return &mLayer->region; diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h index 4d8620b..769ef49 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -50,9 +50,9 @@ public: virtual ~LayerRenderer(); virtual void onViewportInitialized() { /* do nothing */ } - virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); - virtual status_t clear(float left, float top, float right, float bottom, bool opaque); - virtual void finish(); + virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque); + virtual void clear(float left, float top, float right, float bottom, bool opaque); + virtual bool finish(); static Layer* createTextureLayer(RenderState& renderState); static Layer* createRenderLayer(RenderState& renderState, uint32_t width, uint32_t height); @@ -68,7 +68,7 @@ protected: virtual void ensureStencilBuffer(); virtual bool hasLayer() const; virtual Region* getRegion() const; - virtual GLuint getTargetFbo() const; + virtual GLuint onGetTargetFbo() const; virtual bool suppressErrorChecks() const; private: diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 36d1068..c113164 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -36,14 +36,17 @@ #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" #include "Fence.h" -#include "RenderState.h" +#include "GammaFontRenderer.h" +#include "Patch.h" #include "PathTessellator.h" #include "Properties.h" +#include "RenderNode.h" +#include "RenderState.h" #include "ShadowTessellator.h" #include "SkiaShader.h" -#include "utils/GLUtils.h" #include "Vector.h" #include "VertexBuffer.h" +#include "utils/GLUtils.h" #if DEBUG_DETAILED_EVENTS #define EVENT_LOGD(...) eventMarkDEBUG(__VA_ARGS__) @@ -144,13 +147,15 @@ static inline T min(T a, T b) { /////////////////////////////////////////////////////////////////////////////// OpenGLRenderer::OpenGLRenderer(RenderState& renderState) - : mFrameStarted(false) + : mState(*this) + , mFrameStarted(false) , mCaches(Caches::getInstance()) , mExtensions(Extensions::getInstance()) , mRenderState(renderState) , mScissorOptimizationDisabled(false) , mSuppressTiling(false) , mFirstFrameAfterResize(true) + , mDirty(false) , mLightCenter((Vector3){FLT_MIN, FLT_MIN, FLT_MIN}) , mLightRadius(FLT_MIN) , mAmbientShadowAlpha(0) @@ -201,20 +206,20 @@ void OpenGLRenderer::onViewportInitialized() { void OpenGLRenderer::setupFrameState(float left, float top, float right, float bottom, bool opaque) { mCaches.clearGarbage(); - initializeSaveStack(left, top, right, bottom, mLightCenter); + mState.initializeSaveStack(left, top, right, bottom, mLightCenter); mOpaque = opaque; mTilingClip.set(left, top, right, bottom); } -status_t OpenGLRenderer::startFrame() { - if (mFrameStarted) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::startFrame() { + if (mFrameStarted) return; mFrameStarted = true; - mDirtyClip = true; + mState.setDirtyClip(true); discardFramebuffer(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom); - mRenderState.setViewport(getWidth(), getHeight()); + mRenderState.setViewport(mState.getWidth(), mState.getHeight()); // Functors break the tiling extension in pretty spectacular ways // This ensures we don't use tiling when a functor is going to be @@ -227,11 +232,11 @@ status_t OpenGLRenderer::startFrame() { debugOverdraw(true, true); - return clear(mTilingClip.left, mTilingClip.top, + clear(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom, mOpaque); } -status_t OpenGLRenderer::prepareDirty(float left, float top, +void OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { setupFrameState(left, top, right, bottom, opaque); @@ -244,10 +249,8 @@ status_t OpenGLRenderer::prepareDirty(float left, float top, syncState(); updateLayers(); } else { - return startFrame(); + startFrame(); } - - return DrawGlInfo::kStatusDone; } void OpenGLRenderer::discardFramebuffer(float left, float top, float right, float bottom) { @@ -255,8 +258,8 @@ void OpenGLRenderer::discardFramebuffer(float left, float top, float right, floa // perform a discard to let the driver know we don't need to preserve // the back buffer for this frame. if (mExtensions.hasDiscardFramebuffer() && - left <= 0.0f && top <= 0.0f && right >= getWidth() && bottom >= getHeight()) { - const bool isFbo = getTargetFbo() == 0; + left <= 0.0f && top <= 0.0f && right >= mState.getWidth() && bottom >= mState.getHeight()) { + const bool isFbo = onGetTargetFbo() == 0; const GLenum attachments[] = { isFbo ? (const GLenum) GL_COLOR_EXT : (const GLenum) GL_COLOR_ATTACHMENT0, isFbo ? (const GLenum) GL_STENCIL_EXT : (const GLenum) GL_STENCIL_ATTACHMENT }; @@ -264,16 +267,16 @@ void OpenGLRenderer::discardFramebuffer(float left, float top, float right, floa } } -status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) { +void OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) { if (!opaque) { mCaches.enableScissor(); mCaches.setScissor(left, getViewportHeight() - bottom, right - left, bottom - top); glClear(GL_COLOR_BUFFER_BIT); - return DrawGlInfo::kStatusDrew; + mDirty = true; + return; } mCaches.resetScissor(); - return DrawGlInfo::kStatusDone; } void OpenGLRenderer::syncState() { @@ -321,13 +324,13 @@ void OpenGLRenderer::endTiling() { if (!mSuppressTiling) mCaches.endTiling(); } -void OpenGLRenderer::finish() { +bool OpenGLRenderer::finish() { renderOverdraw(); endTiling(); // When finish() is invoked on FBO 0 we've reached the end // of the current frame - if (getTargetFbo() == 0) { + if (onGetTargetFbo() == 0) { mCaches.pathCache.trim(); mCaches.tessellationCache.trim(); } @@ -347,6 +350,8 @@ void OpenGLRenderer::finish() { } mFrameStarted = false; + + return reportAndClearDirty(); } void OpenGLRenderer::resumeAfterLayer() { @@ -358,10 +363,10 @@ void OpenGLRenderer::resumeAfterLayer() { dirtyClip(); } -status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { + if (mState.currentlyIgnored()) return; - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); // Since we don't know what the functor will draw, let's dirty @@ -380,9 +385,9 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { info.height = getViewportHeight(); currentTransform()->copyTo(&info.transform[0]); - bool prevDirtyClip = mDirtyClip; + bool prevDirtyClip = mState.getDirtyClip(); // setup GL state for functor - if (mDirtyClip) { + if (mState.getDirtyClip()) { setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt() } if (mCaches.enableScissor() || prevDirtyClip) { @@ -393,7 +398,7 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { // Scissor may have been modified, reset dirty clip dirtyClip(); - return DrawGlInfo::kStatusDrew; + mDirty = true; } /////////////////////////////////////////////////////////////////////////////// @@ -432,11 +437,11 @@ void OpenGLRenderer::debugOverdraw(bool enable, bool clear) { } void OpenGLRenderer::renderOverdraw() { - if (mCaches.debugOverdraw && getTargetFbo() == 0) { + if (mCaches.debugOverdraw && onGetTargetFbo() == 0) { const Rect* clip = &mTilingClip; mCaches.enableScissor(); - mCaches.setScissor(clip->left, firstSnapshot()->getViewportHeight() - clip->bottom, + mCaches.setScissor(clip->left, mState.firstSnapshot()->getViewportHeight() - clip->bottom, clip->right - clip->left, clip->bottom - clip->top); // 1x overdraw @@ -513,7 +518,7 @@ void OpenGLRenderer::updateLayers() { if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { mLayerUpdates.clear(); - mRenderState.bindFramebuffer(getTargetFbo()); + mRenderState.bindFramebuffer(onGetTargetFbo()); } endMark(); } @@ -540,7 +545,7 @@ void OpenGLRenderer::flushLayers() { } mLayerUpdates.clear(); - mRenderState.bindFramebuffer(getTargetFbo()); + mRenderState.bindFramebuffer(onGetTargetFbo()); endMark(); } @@ -622,9 +627,9 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, // force matrix/clip isolation for layer flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag; - const int count = saveSnapshot(flags); + const int count = mState.saveSnapshot(flags); - if (!currentSnapshot()->isIgnored()) { + if (!mState.currentlyIgnored()) { createLayer(left, top, right, bottom, paint, flags, convexMask); } @@ -637,7 +642,7 @@ void OpenGLRenderer::calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool currentTransform()->mapRect(bounds); // Layers only make sense if they are in the framebuffer's bounds - if (bounds.intersect(*currentClipRect())) { + if (bounds.intersect(*mState.currentClipRect())) { // We cannot work with sub-pixels in this case bounds.snapToPixelBoundaries(); @@ -671,17 +676,17 @@ void OpenGLRenderer::updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize || bounds.getHeight() > mCaches.maxTextureSize || (fboLayer && clip.isEmpty())) { - mSnapshot->empty = fboLayer; + writableSnapshot()->empty = fboLayer; } else { - mSnapshot->invisible = mSnapshot->invisible || (alpha <= 0 && fboLayer); + writableSnapshot()->invisible = writableSnapshot()->invisible || (alpha <= 0 && fboLayer); } } int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom, const SkPaint* paint, int flags) { - const int count = saveSnapshot(flags); + const int count = mState.saveSnapshot(flags); - if (!currentSnapshot()->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) { + if (!mState.currentlyIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) { // initialize the snapshot as though it almost represents an FBO layer so deferred draw // operations will be able to store and restore the current clip and transform info, and // quick rejection will be correct (for display lists) @@ -691,11 +696,11 @@ int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float calculateLayerBoundsAndClip(bounds, clip, true); updateSnapshotIgnoreForLayer(bounds, clip, true, getAlphaDirect(paint)); - if (!currentSnapshot()->isIgnored()) { - mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f); - mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom); - mSnapshot->initializeViewport(bounds.getWidth(), bounds.getHeight()); - mSnapshot->roundRectClipState = NULL; + if (!mState.currentlyIgnored()) { + writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f); + writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom); + writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight()); + writableSnapshot()->roundRectClipState = NULL; } } @@ -769,7 +774,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto updateSnapshotIgnoreForLayer(bounds, clip, fboLayer, getAlphaDirect(paint)); // Bail out if we won't draw in this snapshot - if (currentSnapshot()->isIgnored()) { + if (mState.currentlyIgnored()) { return false; } @@ -789,8 +794,8 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto layer->setConvexMask(convexMask); // note: the mask must be cleared before returning to the cache // Save the layer in the snapshot - mSnapshot->flags |= Snapshot::kFlagIsLayer; - mSnapshot->layer = layer; + writableSnapshot()->flags |= Snapshot::kFlagIsLayer; + writableSnapshot()->layer = layer; ATRACE_FORMAT_BEGIN("%ssaveLayer %ux%u", fboLayer ? "" : "unclipped ", @@ -828,13 +833,13 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { layer->clipRect.set(clip); layer->setFbo(mCaches.fboCache.get()); - mSnapshot->region = &mSnapshot->layer->region; - mSnapshot->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer; - mSnapshot->fbo = layer->getFbo(); - mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f); - mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom); - mSnapshot->initializeViewport(bounds.getWidth(), bounds.getHeight()); - mSnapshot->roundRectClipState = NULL; + writableSnapshot()->region = &writableSnapshot()->layer->region; + writableSnapshot()->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer; + writableSnapshot()->fbo = layer->getFbo(); + writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f); + writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom); + writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight()); + writableSnapshot()->roundRectClipState = NULL; endTiling(); debugOverdraw(false, false); @@ -881,7 +886,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto const bool fboLayer = removed.flags & Snapshot::kFlagIsFboLayer; bool clipRequired = false; - calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom, + mState.calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom, &clipRequired, NULL, false); // safely ignore return, should never be rejected mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); @@ -926,7 +931,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto save(0); // the layer contains screen buffer content that shouldn't be alpha modulated // (and any necessary alpha modulation was handled drawing into the layer) - mSnapshot->alpha = 1.0f; + writableSnapshot()->alpha = 1.0f; composeLayerRect(layer, rect, true); restore(); } @@ -1036,13 +1041,13 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) * operations are correctly counted twice for overdraw. NOTE: assumes composeLayerRegion only used * by saveLayer's restore */ -#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \ - DRAW_COMMAND; \ - if (CC_UNLIKELY(mCaches.debugOverdraw && getTargetFbo() == 0 && COND)) { \ - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \ - DRAW_COMMAND; \ - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \ - } \ +#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \ + DRAW_COMMAND; \ + if (CC_UNLIKELY(mCaches.debugOverdraw && onGetTargetFbo() == 0 && COND)) { \ + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \ + DRAW_COMMAND; \ + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \ + } \ } #define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND) @@ -1271,7 +1276,7 @@ void OpenGLRenderer::dirtyLayer(const float left, const float top, } void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) { - if (bounds.intersect(*currentClipRect())) { + if (bounds.intersect(*mState.currentClipRect())) { bounds.snapToPixelBoundaries(); android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom); if (!dirty.isEmpty()) { @@ -1299,7 +1304,7 @@ void OpenGLRenderer::clearLayerRegions() { const size_t count = mLayers.size(); if (count == 0) return; - if (!currentSnapshot()->isIgnored()) { + if (!mState.currentlyIgnored()) { EVENT_LOGD("clearLayerRegions"); // Doing several glScissor/glClear here can negatively impact // GPUs with a tiler architecture, instead we draw quads with @@ -1355,7 +1360,7 @@ void OpenGLRenderer::clearLayerRegions() { /////////////////////////////////////////////////////////////////////////////// bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDeferFlags) { - const Rect* currentClip = currentClipRect(); + const Rect* currentClip = mState.currentClipRect(); const mat4* currentMatrix = currentTransform(); if (stateDeferFlags & kStateDeferFlag_Draw) { @@ -1408,12 +1413,12 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDef void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) { setMatrix(state.mMatrix); - mSnapshot->alpha = state.mAlpha; + writableSnapshot()->alpha = state.mAlpha; mDrawModifiers = state.mDrawModifiers; - mSnapshot->roundRectClipState = state.mRoundRectClipState; + writableSnapshot()->roundRectClipState = state.mRoundRectClipState; if (state.mClipValid && !skipClipRestore) { - mSnapshot->setClip(state.mClip.left, state.mClip.top, + writableSnapshot()->setClip(state.mClip.left, state.mClip.top, state.mClip.right, state.mClip.bottom); dirtyClip(); } @@ -1428,9 +1433,9 @@ void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool */ void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) { if (clipRect != NULL) { - mSnapshot->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); + writableSnapshot()->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); } else { - mSnapshot->setClip(0, 0, getWidth(), getHeight()); + writableSnapshot()->setClip(0, 0, mState.getWidth(), mState.getHeight()); } dirtyClip(); mCaches.setScissorEnabled(clipRect != NULL || mScissorOptimizationDisabled); @@ -1441,12 +1446,12 @@ void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) { /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::setScissorFromClip() { - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); if (mCaches.setScissor(clip.left, getViewportHeight() - clip.bottom, clip.getWidth(), clip.getHeight())) { - mDirtyClip = false; + mState.setDirtyClip(false); } } @@ -1482,7 +1487,7 @@ void OpenGLRenderer::setStencilFromClip() { // NOTE: The order here is important, we must set dirtyClip to false // before any draw call to avoid calling back into this method - mDirtyClip = false; + mState.setDirtyClip(false); ensureStencilBuffer(); @@ -1551,7 +1556,7 @@ bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, bool clipRequired = false; bool roundRectClipRequired = false; - if (calculateQuickRejectForScissor(left, top, right, bottom, + if (mState.calculateQuickRejectForScissor(left, top, right, bottom, &clipRequired, &roundRectClipRequired, snapOut)) { return true; } @@ -1583,7 +1588,7 @@ void OpenGLRenderer::setupDraw(bool clearLayer) { if (clearLayer) clearLayerRegions(); // Make sure setScissor & setStencil happen at the beginning of // this method - if (mDirtyClip) { + if (mState.getDirtyClip()) { if (mCaches.scissorEnabled) { setScissorFromClip(); } @@ -1721,7 +1726,7 @@ void OpenGLRenderer::setupDrawProgram() { useProgram(mCaches.programCache.get(mDescription)); if (mDescription.hasRoundRectClip) { // TODO: avoid doing this repeatedly, stashing state pointer in program - const RoundRectClipState* state = mSnapshot->roundRectClipState; + const RoundRectClipState* state = writableSnapshot()->roundRectClipState; const Rect& innerRect = state->innerRect; glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"), innerRect.left, innerRect.top, @@ -1749,7 +1754,7 @@ void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset, bool dirty = right - left > 0.0f && bottom - top > 0.0f; const Matrix4& transformMatrix = ignoreTransform ? Matrix4::identity() : *currentTransform(); - mCaches.currentProgram->set(mSnapshot->getOrthoMatrix(), mModelViewMatrix, transformMatrix, offset); + mCaches.currentProgram->set(writableSnapshot()->getOrthoMatrix(), mModelViewMatrix, transformMatrix, offset); if (dirty && mTrackDirtyRegions) { if (!ignoreTransform) { dirtyLayer(left, top, right, bottom, *currentTransform()); @@ -1927,33 +1932,32 @@ void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { // Drawing /////////////////////////////////////////////////////////////////////////////// -status_t OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) { - status_t status; +void OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) { // All the usual checks and setup operations (quickReject, setupDraw, etc.) // will be performed by the display list itself if (renderNode && renderNode->isRenderable()) { // compute 3d ordering renderNode->computeOrdering(); if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { - status = startFrame(); + startFrame(); ReplayStateStruct replayStruct(*this, dirty, replayFlags); renderNode->replay(replayStruct, 0); - return status | replayStruct.mDrawGlStatus; + return; } - DeferredDisplayList deferredList(*currentClipRect()); + DeferredDisplayList deferredList(*mState.currentClipRect()); DeferStateStruct deferStruct(deferredList, *this, replayFlags); renderNode->defer(deferStruct, 0); flushLayers(); - status = startFrame(); + startFrame(); - return deferredList.flush(*this, dirty) | status; + deferredList.flush(*this, dirty); + } else { + // Even if there is no drawing command(Ex: invisible), + // it still needs startFrame to clear buffer and start tiling. + startFrame(); } - - // Even if there is no drawing command(Ex: invisible), - // it still needs startFrame to clear buffer and start tiling. - return startFrame(); } void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint) { @@ -1985,12 +1989,12 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, co * will not set the scissor enable or dirty the current layer, if any. * The caller is responsible for properly dirtying the current layer. */ -status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, +void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); @@ -2011,17 +2015,17 @@ status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* kModelViewMode_Translate, false); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { +void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); Texture* texture = getTexture(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) { @@ -2030,12 +2034,12 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { +void OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) { if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); @@ -2048,13 +2052,13 @@ status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* p drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, +void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) { - if (!vertices || currentSnapshot()->isIgnored()) { - return DrawGlInfo::kStatusDone; + if (!vertices || mState.currentlyIgnored()) { + return; } // TODO: use quickReject on bounds from vertices @@ -2121,14 +2125,14 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i if (quickRejectSetupScissor(left, top, right, bottom)) { if (cleanupColors) delete[] colors; - return DrawGlInfo::kStatusDone; + return; } if (!texture) { texture = mCaches.textureCache.get(bitmap); if (!texture) { if (cleanupColors) delete[] colors; - return DrawGlInfo::kStatusDone; + return; } } const AutoTexture autoCleanup(texture); @@ -2168,20 +2172,20 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i if (cleanupColors) delete[] colors; - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, +void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) { - return DrawGlInfo::kStatusDone; + return; } mCaches.activeTexture(0); Texture* texture = getTexture(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float width = texture->width; @@ -2255,33 +2259,33 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, +void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap); const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(), right - left, bottom - top, patch); - return drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint); + drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint); } -status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, +void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } if (CC_LIKELY(mesh && mesh->verticesCount > 0)) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); texture->setWrap(GL_CLAMP_TO_EDGE, true); @@ -2323,7 +2327,7 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /** @@ -2331,11 +2335,11 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, * will not set the scissor enable or dirty the current layer, if any. * The caller is responsible for properly dirtying the current layer. */ -status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, +void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) { mCaches.activeTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); texture->setWrap(GL_CLAMP_TO_EDGE, true); @@ -2345,15 +2349,15 @@ status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* texture->blend, &vertices[0].x, &vertices[0].u, GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, +void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer, const SkPaint* paint, int displayFlags) { // not missing call to quickReject/dirtyLayer, always done at a higher level if (!vertexBuffer.getVertexCount()) { // no vertices to draw - return DrawGlInfo::kStatusDone; + return; } Rect bounds(vertexBuffer.getBounds()); @@ -2366,7 +2370,7 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, setupDraw(); setupDrawNoTexture(); if (isAA) setupDrawVertexAlpha((displayFlags & kVertexBuffer_ShadowInterp)); - setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha); + setupDrawColor(color, ((color >> 24) & 0xFF) * writableSnapshot()->alpha); setupDrawColorFilter(getColorFilter(paint)); setupDrawShader(getShader(paint)); setupDrawBlending(paint, isAA); @@ -2411,7 +2415,7 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, glDisableVertexAttribArray(alphaSlot); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /** @@ -2423,11 +2427,11 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, * * Doesn't yet support joins, caps, or path effects. */ -status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) { +void OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) { VertexBuffer vertexBuffer; // TODO: try clipping large paths to viewport PathTessellator::tessellatePath(path, paint, *currentTransform(), vertexBuffer); - return drawVertexBuffer(vertexBuffer, paint); + drawVertexBuffer(vertexBuffer, paint); } /** @@ -2441,8 +2445,8 @@ status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint * TODO: try using a fixed input buffer for non-capped lines as in text rendering. this may reduce * memory transfer by removing need for degenerate vertices. */ -status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored() || count < 4) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) { + if (mState.currentlyIgnored() || count < 4) return; count &= ~0x3; // round down to nearest four @@ -2451,15 +2455,15 @@ status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint const Rect& bounds = buffer.getBounds(); if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) { - return DrawGlInfo::kStatusDone; + return; } int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset; - return drawVertexBuffer(buffer, paint, displayFlags); + drawVertexBuffer(buffer, paint, displayFlags); } -status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored() || count < 2) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { + if (mState.currentlyIgnored() || count < 2) return; count &= ~0x1; // round down to nearest two @@ -2468,18 +2472,20 @@ status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPain const Rect& bounds = buffer.getBounds(); if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) { - return DrawGlInfo::kStatusDone; + return; } int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset; - return drawVertexBuffer(buffer, paint, displayFlags); + drawVertexBuffer(buffer, paint, displayFlags); + + mDirty = true; } -status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { +void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { // No need to check against the clip, we fill the clip region - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; + if (mState.currentlyIgnored()) return; - Rect clip(*currentClipRect()); + Rect clip(*mState.currentClipRect()); clip.snapToPixelBoundaries(); SkPaint paint; @@ -2488,12 +2494,12 @@ status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { drawColorRect(clip.left, clip.top, clip.right, clip.bottom, &paint, true); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, +void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint) { - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float x = left + texture->left - texture->offset; @@ -2501,79 +2507,79 @@ status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* tex drawPathTexture(texture, x, y, paint); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, +void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } if (p->getPathEffect() != 0) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getRoundRect( right - left, bottom - top, rx, ry, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + } else { + const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect( + *currentTransform(), *p, right - left, bottom - top, rx, ry); + drawVertexBuffer(left, top, *vertexBuffer, p); } - - const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect( - *currentTransform(), *p, right - left, bottom - top, rx, ry); - return drawVertexBuffer(left, top, *vertexBuffer, p); } -status_t OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) { - if (currentSnapshot()->isIgnored() +void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) { + if (mState.currentlyIgnored() || quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } if (p->getPathEffect() != 0) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getCircle(radius, p); - return drawShape(x - radius, y - radius, texture, p); - } - - SkPath path; - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - path.addCircle(x, y, radius + p->getStrokeWidth() / 2); + drawShape(x - radius, y - radius, texture, p); } else { - path.addCircle(x, y, radius); + SkPath path; + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + path.addCircle(x, y, radius + p->getStrokeWidth() / 2); + } else { + path.addCircle(x, y, radius); + } + drawConvexPath(path, p); } - return drawConvexPath(path, p); } -status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom, +void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } if (p->getPathEffect() != 0) { mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getOval(right - left, bottom - top, p); - return drawShape(left, top, texture, p); - } - - SkPath path; - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + drawShape(left, top, texture, p); + } else { + SkPath path; + SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + } + path.addOval(rect); + drawConvexPath(path, p); } - path.addOval(rect); - return drawConvexPath(path, p); } -status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom, +void OpenGLRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180) @@ -2581,9 +2587,9 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getArc(right - left, bottom - top, startAngle, sweepAngle, useCenter, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + return; } - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); @@ -2597,18 +2603,18 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto if (useCenter) { path.close(); } - return drawConvexPath(path, p); + drawConvexPath(path, p); } // See SkPaintDefaults.h #define SkPaintDefaults_MiterLimit SkIntToScalar(4) -status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, +void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { - if (currentSnapshot()->isIgnored() + if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) || paintWillNotDraw(*p)) { - return DrawGlInfo::kStatusDone; + return; } if (p->getStyle() != SkPaint::kFill_Style) { @@ -2618,25 +2624,26 @@ status_t OpenGLRenderer::drawRect(float left, float top, float right, float bott mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.getRect(right - left, bottom - top, p); - return drawShape(left, top, texture, p); + drawShape(left, top, texture, p); + } else { + SkPath path; + SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + } + path.addRect(rect); + drawConvexPath(path, p); } + } else { + if (p->isAntiAlias() && !currentTransform()->isSimple()) { + SkPath path; + path.addRect(left, top, right, bottom); + drawConvexPath(path, p); + } else { + drawColorRect(left, top, right, bottom, p); - SkPath path; - SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2); + mDirty = true; } - path.addRect(rect); - return drawConvexPath(path, p); - } - - if (p->isAntiAlias() && !currentTransform()->isSimple()) { - SkPath path; - path.addRect(left, top, right, bottom); - return drawConvexPath(path, p); - } else { - drawColorRect(left, top, right, bottom, p); - return DrawGlInfo::kStatusDrew; } } @@ -2663,7 +2670,7 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, const float sx = x - shadow->left + textShadow.dx; const float sy = y - shadow->top + textShadow.dy; - const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * mSnapshot->alpha; + const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * writableSnapshot()->alpha; if (getShader(paint)) { textShadow.color = SK_ColorWHITE; } @@ -2687,19 +2694,19 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, } bool OpenGLRenderer::canSkipText(const SkPaint* paint) const { - float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * mSnapshot->alpha; + float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * currentSnapshot()->alpha; return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode; } -status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, +void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint) { - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) { - return DrawGlInfo::kStatusDone; + if (text == NULL || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) { + return; } // NOTE: Skia does not support perspective transform on drawPosText yet if (!currentTransform()->isSimple()) { - return DrawGlInfo::kStatusDone; + return; } mCaches.enableScissor(); @@ -2731,7 +2738,7 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count } fontRenderer.setTextureFiltering(linearFilter); - const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip(); + const Rect* clip = pureTranslate ? writableSnapshot()->clipRect : &writableSnapshot()->getLocalClip(); Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); const bool hasActiveLayer = hasLayer(); @@ -2747,7 +2754,7 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count } } - return DrawGlInfo::kStatusDrew; + mDirty = true; } bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outMatrix) const { @@ -2771,16 +2778,79 @@ bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outM return true; } -status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, +int OpenGLRenderer::getSaveCount() const { + return mState.getSaveCount(); +} + +int OpenGLRenderer::save(int flags) { + return mState.save(flags); +} + +void OpenGLRenderer::restore() { + return mState.restore(); +} + +void OpenGLRenderer::restoreToCount(int saveCount) { + return mState.restoreToCount(saveCount); +} + +void OpenGLRenderer::translate(float dx, float dy, float dz) { + return mState.translate(dx, dy, dz); +} + +void OpenGLRenderer::rotate(float degrees) { + return mState.rotate(degrees); +} + +void OpenGLRenderer::scale(float sx, float sy) { + return mState.scale(sx, sy); +} + +void OpenGLRenderer::skew(float sx, float sy) { + return mState.skew(sx, sy); +} + +void OpenGLRenderer::setMatrix(const Matrix4& matrix) { + mState.setMatrix(matrix); +} + +void OpenGLRenderer::concatMatrix(const Matrix4& matrix) { + mState.concatMatrix(matrix); +} + +bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { + return mState.clipRect(left, top, right, bottom, op); +} + +bool OpenGLRenderer::clipPath(const SkPath* path, SkRegion::Op op) { + return mState.clipPath(path, op); +} + +bool OpenGLRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { + return mState.clipRegion(region, op); +} + +void OpenGLRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { + mState.setClippingOutline(allocator, outline); +} + +void OpenGLRenderer::setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius, bool highPriority) { + mState.setClippingRoundRect(allocator, rect, radius, highPriority); +} + + + +void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { if (drawOpMode == kDrawOpMode_Immediate) { // The checks for corner-case ignorable text and quick rejection is only done for immediate // drawing as ops from DeferredDisplayList are already filtered for these - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint) || + if (text == NULL || count == 0 || mState.currentlyIgnored() || canSkipText(paint) || quickRejectSetupScissor(bounds)) { - return DrawGlInfo::kStatusDone; + return; } } @@ -2828,7 +2898,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f fontRenderer.setTextureFiltering(linearFilter); // TODO: Implement better clipping for scaled/rotated text - const Rect* clip = !pureTranslate ? NULL : currentClipRect(); + const Rect* clip = !pureTranslate ? NULL : mState.currentClipRect(); Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); bool status; @@ -2855,13 +2925,13 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f drawTextDecorations(totalAdvance, oldX, oldY, paint); - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, +void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { - if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) { - return DrawGlInfo::kStatusDone; + if (text == NULL || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) { + return; } // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics @@ -2876,7 +2946,7 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co getAlphaAndMode(paint, &alpha, &mode); TextSetupFunctor functor(this, 0.0f, 0.0f, false, alpha, mode, paint); - const Rect* clip = &mSnapshot->getLocalClip(); + const Rect* clip = &writableSnapshot()->getLocalClip(); Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); const bool hasActiveLayer = hasLayer(); @@ -2889,29 +2959,28 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co } } - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) { + if (mState.currentlyIgnored()) return; mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.get(path, paint); - if (!texture) return DrawGlInfo::kStatusDone; + if (!texture) return; const AutoTexture autoCleanup(texture); const float x = texture->left - texture->offset; const float y = texture->top - texture->offset; drawPathTexture(texture, x, y, paint); - - return DrawGlInfo::kStatusDrew; + mDirty = true; } -status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { +void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { if (!layer) { - return DrawGlInfo::kStatusDone; + return; } mat4* transform = NULL; @@ -2924,14 +2993,14 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { } bool clipRequired = false; - const bool rejected = calculateQuickRejectForScissor(x, y, + const bool rejected = mState.calculateQuickRejectForScissor(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired, NULL, false); if (rejected) { if (transform && !transform->isIdentity()) { restore(); } - return DrawGlInfo::kStatusDone; + return; } EVENT_LOGD("drawLayer," RECT_STRING ", clipRequired %d", x, y, @@ -3006,53 +3075,16 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { restore(); } - return DrawGlInfo::kStatusDrew; + mDirty = true; } /////////////////////////////////////////////////////////////////////////////// // Draw filters /////////////////////////////////////////////////////////////////////////////// - -void OpenGLRenderer::resetPaintFilter() { - // when clearing the PaintFilter, the masks should also be cleared for simple DrawModifier - // comparison, see MergingDrawBatch::canMergeWith - mDrawModifiers.mHasDrawFilter = false; - mDrawModifiers.mPaintFilterClearBits = 0; - mDrawModifiers.mPaintFilterSetBits = 0; -} - -void OpenGLRenderer::setupPaintFilter(int clearBits, int setBits) { - // TODO: don't bother with boolean, it's redundant with clear/set bits - mDrawModifiers.mHasDrawFilter = true; - mDrawModifiers.mPaintFilterClearBits = clearBits & SkPaint::kAllFlags; - mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags; -} - -const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) { - // TODO: use CompatFlagsDrawFilter here, and combine logic with android/graphics/DrawFilter.cpp - // to avoid clobbering 0x02 paint flag - - // Equivalent to the Java Paint's FILTER_BITMAP_FLAG. - static const uint32_t sFilterBitmapFlag = 0x02; - - if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) { - return paint; - } - - const uint32_t clearBits = mDrawModifiers.mPaintFilterClearBits; - const uint32_t setBits = mDrawModifiers.mPaintFilterSetBits; - - const uint32_t flags = (paint->getFlags() & ~clearBits) | setBits; - mFilteredPaint = *paint; - mFilteredPaint.setFlags(flags); - - // check if paint filter trying to override bitmap filter - if ((clearBits | setBits) & sFilterBitmapFlag) { - mFilteredPaint.setFilterLevel(flags & sFilterBitmapFlag - ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel); - } - - return &mFilteredPaint; +void OpenGLRenderer::setDrawFilter(SkDrawFilter* filter) { + // We should never get here since we apply the draw filter when stashing + // the paints in the DisplayList. + LOG_ALWAYS_FATAL("OpenGLRenderer does not directly support DrawFilters"); } /////////////////////////////////////////////////////////////////////////////// @@ -3145,17 +3177,17 @@ void OpenGLRenderer::drawTextDecorations(float underlineWidth, float x, float y, } } -status_t OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { - if (currentSnapshot()->isIgnored()) { - return DrawGlInfo::kStatusDone; +void OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { + if (mState.currentlyIgnored()) { + return; } - return drawColorRects(rects, count, paint, false, true, true); + drawColorRects(rects, count, paint, false, true, true); } -status_t OpenGLRenderer::drawShadow(float casterAlpha, +void OpenGLRenderer::drawShadow(float casterAlpha, const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer) { - if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; + if (mState.currentlyIgnored()) return; // TODO: use quickRejectWithScissor. For now, always force enable scissor. mCaches.enableScissor(); @@ -3182,13 +3214,13 @@ status_t OpenGLRenderer::drawShadow(float casterAlpha, drawVertexBuffer(*spotShadowVertexBuffer, &paint, kVertexBuffer_ShadowInterp); } - return DrawGlInfo::kStatusDrew; + mDirty=true; } -status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint, +void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint, bool ignoreTransform, bool dirty, bool clip) { if (count == 0) { - return DrawGlInfo::kStatusDone; + return; } int color = paint->getColor(); @@ -3223,7 +3255,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkP } if (clip && quickRejectSetupScissor(left, top, right, bottom)) { - return DrawGlInfo::kStatusDone; + return; } setupDraw(); @@ -3246,7 +3278,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkP issueIndexedQuadDraw(&mesh[0], count / 4); - return DrawGlInfo::kStatusDrew; + mDirty = true; } void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, @@ -3397,7 +3429,7 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description, bool swapSrcDst) { - if (mSnapshot->roundRectClipState != NULL /*&& !mSkipOutlineClip*/) { + if (writableSnapshot()->roundRectClipState != NULL /*&& !mSkipOutlineClip*/) { blend = true; mDescription.hasRoundRectClip = true; } diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index e1c3d10..fde9e0f 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -38,6 +38,7 @@ #include <androidfw/ResourceTypes.h> +#include "CanvasState.h" #include "Debug.h" #include "Extensions.h" #include "Matrix.h" @@ -45,11 +46,9 @@ #include "Rect.h" #include "Renderer.h" #include "Snapshot.h" -#include "StatefulBaseRenderer.h" #include "UvMapper.h" #include "Vertex.h" #include "Caches.h" -#include "CanvasProperty.h" class SkShader; @@ -72,11 +71,6 @@ struct DrawModifiers { } float mOverrideLayerAlpha; - - // Draw filters - bool mHasDrawFilter; - int mPaintFilterClearBits; - int mPaintFilterSetBits; }; enum StateDeferFlags { @@ -123,7 +117,7 @@ enum ModelViewMode { /** * OpenGL Renderer implementation. */ -class OpenGLRenderer : public StatefulBaseRenderer { +class OpenGLRenderer : public Renderer, public CanvasStateClient { public: OpenGLRenderer(RenderState& renderState); virtual ~OpenGLRenderer(); @@ -132,11 +126,13 @@ public: void initLight(const Vector3& lightCenter, float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); - virtual void onViewportInitialized(); - virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); - virtual void finish(); + virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque); + virtual void prepare(bool opaque) { + prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque); + } + virtual bool finish(); - virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty); + virtual void callDrawGLFunction(Functor* functor, Rect& dirty); void pushLayerUpdate(Layer* layer); void cancelLayerUpdate(Layer* layer); @@ -156,56 +152,53 @@ public: int saveLayerDeferred(float left, float top, float right, float bottom, const SkPaint* paint, int flags); - virtual status_t drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1); - virtual status_t drawLayer(Layer* layer, float x, float y); - virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); - status_t drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, + virtual void drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1); + virtual void drawLayer(Layer* layer, float x, float y); + virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); + void drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint); - virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, + virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint); - virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint); - virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, + virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint); + virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint); - status_t drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, + void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint); - virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, + virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint); - status_t drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, + void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint); - virtual status_t drawColor(int color, SkXfermode::Mode mode); - virtual status_t drawRect(float left, float top, float right, float bottom, + virtual void drawColor(int color, SkXfermode::Mode mode); + virtual void drawRect(float left, float top, float right, float bottom, const SkPaint* paint); - virtual status_t drawRoundRect(float left, float top, float right, float bottom, + virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* paint); - virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint); - virtual status_t drawOval(float left, float top, float right, float bottom, + virtual void drawCircle(float x, float y, float radius, const SkPaint* paint); + virtual void drawOval(float left, float top, float right, float bottom, const SkPaint* paint); - virtual status_t drawArc(float left, float top, float right, float bottom, + virtual void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint); - virtual status_t drawPath(const SkPath* path, const SkPaint* paint); - virtual status_t drawLines(const float* points, int count, const SkPaint* paint); - virtual status_t drawPoints(const float* points, int count, const SkPaint* paint); - virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, + virtual void drawPath(const SkPath* path, const SkPaint* paint); + virtual void drawLines(const float* points, int count, const SkPaint* paint); + virtual void drawPoints(const float* points, int count, const SkPaint* paint); + virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint); - virtual status_t drawPosText(const char* text, int bytesCount, int count, + virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint); - virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, + virtual void drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode = kDrawOpMode_Immediate); - virtual status_t drawRects(const float* rects, int count, const SkPaint* paint); + virtual void drawRects(const float* rects, int count, const SkPaint* paint); - status_t drawShadow(float casterAlpha, + void drawShadow(float casterAlpha, const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer); - virtual void resetPaintFilter(); - virtual void setupPaintFilter(int clearBits, int setBits); + virtual void setDrawFilter(SkDrawFilter* filter); // If this value is set to < 1.0, it overrides alpha set on layer (see drawBitmap, drawLayer) void setOverrideLayerAlpha(float alpha) { mDrawModifiers.mOverrideLayerAlpha = alpha; } - const SkPaint* filterPaint(const SkPaint* paint); - /** * Store the current display state (most importantly, the current clip and transform), and * additionally map the state's bounds from local to window coordinates. @@ -228,20 +221,16 @@ public: } // simple rect clip - bool isCurrentClipSimple() { - return mSnapshot->clipRegion->isEmpty(); - } + bool isCurrentClipSimple() { return mState.isCurrentClipSimple(); } - int getViewportWidth() { return currentSnapshot()->getViewportWidth(); } - int getViewportHeight() { return currentSnapshot()->getViewportHeight(); } + int getViewportWidth() { return mState.getViewportWidth(); } + int getViewportHeight() { return mState.getViewportHeight(); } /** * Scales the alpha on the current snapshot. This alpha value will be modulated * with other alpha values when drawing primitives. */ - void scaleAlpha(float alpha) { - mSnapshot->alpha *= alpha; - } + void scaleAlpha(float alpha) { mState.scaleAlpha(alpha); } /** * Inserts a named event marker in the stream of GL commands. @@ -334,14 +323,67 @@ public: drawColorRect(left, top, right, bottom, color, SkXfermode::kSrcOver_Mode, true); if (stencilWasEnabled) mCaches.stencil.enableTest(); + mDirty = true; } #endif - const Vector3& getLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); } + const Vector3& getLightCenter() const { return mState.currentLightCenter(); } float getLightRadius() const { return mLightRadius; } uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; } uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; } + /////////////////////////////////////////////////////////////////// + /// State manipulation + + virtual void setViewport(int width, int height) { mState.setViewport(width, height); } + + virtual int getSaveCount() const; + virtual int save(int flags); + virtual void restore(); + virtual void restoreToCount(int saveCount); + + virtual void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); } + virtual void setMatrix(const SkMatrix& matrix) { mState.setMatrix(matrix); } + virtual void concatMatrix(const SkMatrix& matrix) { mState.concatMatrix(matrix); } + + 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 setMatrix(const Matrix4& matrix); // internal only convenience method + void concatMatrix(const Matrix4& matrix); // internal only convenience method + + virtual const Rect& getLocalClipBounds() const { return mState.getLocalClipBounds(); } + const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); } + virtual bool quickRejectConservative(float left, float top, float right, float bottom) const { + return mState.quickRejectConservative(left, top, right, bottom); + } + + 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); + + /** + * 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. + */ + void setClippingOutline(LinearAllocator& allocator, const Outline* outline); + void setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius, bool highPriority = true); + + inline bool hasRectToRectTransform() const { return mState.hasRectToRectTransform(); } + inline const mat4* currentTransform() const { return mState.currentTransform(); } + + /////////////////////////////////////////////////////////////////// + /// CanvasStateClient interface + + virtual void onViewportInitialized(); + virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored); + virtual GLuint onGetTargetFbo() const { return 0; } + protected: /** * Perform the setup specific to a frame. This method does not @@ -353,12 +395,12 @@ protected: * Indicates the start of rendering. This method will setup the * initial OpenGL state (viewport, clearing the buffer, etc.) */ - status_t startFrame(); + void startFrame(); /** * Clears the underlying surface if needed. */ - virtual status_t clear(float left, float top, float right, float bottom, bool opaque); + virtual void clear(float left, float top, float right, float bottom, bool opaque); /** * Call this method after updating a layer during a drawing pass. @@ -405,22 +447,16 @@ protected: * Returns the region of the current layer. */ virtual Region* getRegion() const { - return mSnapshot->region; + return mState.currentRegion(); } /** * Indicates whether rendering is currently targeted at a layer. */ virtual bool hasLayer() const { - return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region; + return (mState.currentFlags() & Snapshot::kFlagFboTarget) && mState.currentRegion(); } - /** - * Returns the name of the FBO this renderer is rendering into. - */ - virtual GLuint getTargetFbo() const { - return 0; - } /** * Renders the specified layer as a textured quad. @@ -473,6 +509,8 @@ protected: inline RenderState& renderState() { return mRenderState; } + CanvasState mState; + private: /** * Discards the content of the framebuffer if supported by the driver. @@ -508,8 +546,6 @@ private: */ void endTiling(); - void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored); - /** * Sets the clipping rectangle using glScissor. The clip is defined by * the current snapshot's clipRect member. @@ -623,7 +659,7 @@ private: * @param dirty True if calling this method should dirty the current layer * @param clip True if the rects should be clipped, false otherwise */ - status_t drawColorRects(const float* rects, int count, const SkPaint* paint, + void drawColorRects(const float* rects, int count, const SkPaint* paint, bool ignoreTransform = false, bool dirty = true, bool clip = true); /** @@ -637,7 +673,7 @@ private: * @param texture The texture reprsenting the shape * @param paint The paint to draw the shape with */ - status_t drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint); + void drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint); /** * Draws the specified texture as an alpha bitmap. Alpha bitmaps obey @@ -657,15 +693,15 @@ private: * @param paint The paint to render with * @param flags flags with which to draw */ - status_t drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer, + void drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer, const SkPaint* paint, int flags = 0); /** * Convenience for translating method */ - status_t drawVertexBuffer(const VertexBuffer& vertexBuffer, + void drawVertexBuffer(const VertexBuffer& vertexBuffer, const SkPaint* paint, int flags = 0) { - return drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags); + drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags); } /** @@ -674,7 +710,7 @@ private: * @param path The hull of the path to draw * @param paint The paint to render with */ - status_t drawConvexPath(const SkPath& path, const SkPaint* paint); + void drawConvexPath(const SkPath& path, const SkPaint* paint); /** * Draws a textured rectangle with the specified texture. The specified coordinates @@ -925,9 +961,7 @@ private: /** * Should be invoked every time the glScissor is modified. */ - inline void dirtyClip() { - mDirtyClip = true; - } + inline void dirtyClip() { mState.setDirtyClip(true); } inline const UvMapper& getMapper(const Texture* texture) { return texture && texture->uvMapper ? *texture->uvMapper : mUvMapper; @@ -940,6 +974,10 @@ private: */ Texture* getTexture(const SkBitmap* bitmap); + bool reportAndClearDirty() { bool ret = mDirty; mDirty = false; return ret; } + inline Snapshot* writableSnapshot() { return mState.writableSnapshot(); } + inline const Snapshot* currentSnapshot() const { return mState.currentSnapshot(); } + /** * Model-view matrix used to position/size objects * @@ -1008,6 +1046,10 @@ private: bool mSkipOutlineClip; + // True if anything has been drawn since the last call to + // reportAndClearDirty() + bool mDirty; + // Lighting + shadows Vector3 mLightCenter; float mLightRadius; diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h index 1ba045d..d5bbfa6 100644 --- a/libs/hwui/Patch.h +++ b/libs/hwui/Patch.h @@ -27,11 +27,12 @@ #include "Rect.h" #include "UvMapper.h" -#include "Vertex.h" namespace android { namespace uirenderer { +class TextureVertex; + /////////////////////////////////////////////////////////////////////////////// // 9-patch structures /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp index 2f2debc..1920fcf 100644 --- a/libs/hwui/PatchCache.cpp +++ b/libs/hwui/PatchCache.cpp @@ -20,6 +20,7 @@ #include <utils/Log.h> #include "Caches.h" +#include "Patch.h" #include "PatchCache.h" #include "Properties.h" diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h index 9f2c9a5..1e40997 100644 --- a/libs/hwui/PatchCache.h +++ b/libs/hwui/PatchCache.h @@ -25,12 +25,13 @@ #include "AssetAtlas.h" #include "Debug.h" -#include "Patch.h" #include "utils/Pair.h" namespace android { namespace uirenderer { +class Patch; + /////////////////////////////////////////////////////////////////////////////// // Defines /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h index bc34188..b0f00c7 100644 --- a/libs/hwui/PathCache.h +++ b/libs/hwui/PathCache.h @@ -24,7 +24,6 @@ #include <utils/Vector.h> #include "Debug.h" -#include "Properties.h" #include "Texture.h" #include "utils/Macros.h" #include "utils/Pair.h" diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h index 38f6f99..9aadba6 100644 --- a/libs/hwui/ProgramCache.h +++ b/libs/hwui/ProgramCache.h @@ -25,7 +25,6 @@ #include "Debug.h" #include "Program.h" -#include "Properties.h" namespace android { namespace uirenderer { diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index fd5ae72..743b2f5 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -33,6 +33,7 @@ #include "DisplayListLogBuffer.h" #include "LayerRenderer.h" #include "OpenGLRenderer.h" +#include "TreeInfo.h" #include "utils/MathUtils.h" #include "renderthread/CanvasContext.h" diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index 2ce7cb7..bbe53ff 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -33,13 +33,10 @@ #include <androidfw/ResourceTypes.h> #include "AnimatorManager.h" -#include "DamageAccumulator.h" #include "Debug.h" #include "Matrix.h" -#include "DeferredDisplayList.h" #include "DisplayList.h" #include "RenderProperties.h" -#include "TreeInfo.h" class SkBitmap; class SkPaint; @@ -61,6 +58,7 @@ class SaveLayerOp; class SaveOp; class RestoreToCountOp; class DrawRenderNodeOp; +class TreeInfo; /** * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties. diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index b936d4b..2b5b811 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -26,8 +26,8 @@ #include <SkCamera.h> #include <SkMatrix.h> #include <SkRegion.h> +#include <SkXfermode.h> -#include "Animator.h" #include "Rect.h" #include "RevealClip.h" #include "Outline.h" diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h index afeef95..aa39a3a 100644 --- a/libs/hwui/RenderState.h +++ b/libs/hwui/RenderState.h @@ -20,15 +20,19 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <utils/Mutex.h> +#include <utils/Functor.h> +#include <utils/RefBase.h> #include <private/hwui/DrawGlInfo.h> -#include "Caches.h" #include "utils/Macros.h" namespace android { namespace uirenderer { +class Caches; +class Layer; + namespace renderthread { class CanvasContext; class RenderThread; diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h index 3159d1e..2b7b567 100644 --- a/libs/hwui/Renderer.h +++ b/libs/hwui/Renderer.h @@ -20,11 +20,12 @@ #include <SkColorFilter.h> #include <SkPaint.h> #include <SkRegion.h> - #include <utils/String8.h> #include "AssetAtlas.h" +class SkDrawFilter; + namespace android { class Functor; @@ -111,7 +112,7 @@ public: * and will not be cleared. If false, the target surface * will be cleared */ - virtual status_t prepare(bool opaque) = 0; + virtual void prepare(bool opaque) = 0; /** * Prepares the renderer to draw a frame. This method must be invoked @@ -127,14 +128,16 @@ public: * and will not be cleared. If false, the target surface * will be cleared in the specified dirty rectangle */ - virtual status_t prepareDirty(float left, float top, float right, float bottom, + virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque) = 0; /** * Indicates the end of a frame. This method must be invoked whenever * the caller is done rendering a frame. + * Returns true if any drawing was done during the frame (the output + * has changed / is "dirty" and should be displayed to the user). */ - virtual void finish() = 0; + virtual bool finish() = 0; // ---------------------------------------------------------------------------- // Canvas state operations @@ -173,58 +176,57 @@ public: virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0; virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0; - // Misc - should be implemented with SkPaint inspection - virtual void resetPaintFilter() = 0; - virtual void setupPaintFilter(int clearBits, int setBits) = 0; + // Misc + virtual void setDrawFilter(SkDrawFilter* filter) = 0; // ---------------------------------------------------------------------------- // Canvas draw operations // ---------------------------------------------------------------------------- - virtual status_t drawColor(int color, SkXfermode::Mode mode) = 0; + virtual void drawColor(int color, SkXfermode::Mode mode) = 0; // Bitmap-based - virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0; - virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, + virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0; + virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) = 0; - virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0; - virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, + virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0; + virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) = 0; - virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, + virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) = 0; // Shapes - virtual status_t drawRect(float left, float top, float right, float bottom, + virtual void drawRect(float left, float top, float right, float bottom, const SkPaint* paint) = 0; - virtual status_t drawRects(const float* rects, int count, const SkPaint* paint) = 0; - virtual status_t drawRoundRect(float left, float top, float right, float bottom, + virtual void drawRects(const float* rects, int count, const SkPaint* paint) = 0; + virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint* paint) = 0; - virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint) = 0; - virtual status_t drawOval(float left, float top, float right, float bottom, + virtual void drawCircle(float x, float y, float radius, const SkPaint* paint) = 0; + virtual void drawOval(float left, float top, float right, float bottom, const SkPaint* paint) = 0; - virtual status_t drawArc(float left, float top, float right, float bottom, + virtual void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) = 0; - virtual status_t drawPath(const SkPath* path, const SkPaint* paint) = 0; - virtual status_t drawLines(const float* points, int count, const SkPaint* paint) = 0; - virtual status_t drawPoints(const float* points, int count, const SkPaint* paint) = 0; + virtual void drawPath(const SkPath* path, const SkPaint* paint) = 0; + virtual void drawLines(const float* points, int count, const SkPaint* paint) = 0; + virtual void drawPoints(const float* points, int count, const SkPaint* paint) = 0; // Text - virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, + virtual void drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode = kDrawOpMode_Immediate) = 0; - virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, + virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) = 0; - virtual status_t drawPosText(const char* text, int bytesCount, int count, + virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, const SkPaint* paint) = 0; // ---------------------------------------------------------------------------- // Canvas draw operations - special // ---------------------------------------------------------------------------- - virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty, + virtual void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) = 0; // TODO: rename for consistency - virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty) = 0; + virtual void callDrawGLFunction(Functor* functor, Rect& dirty) = 0; }; // class Renderer }; // namespace uirenderer diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h index a922d53..c6cd7bf 100644 --- a/libs/hwui/ResourceCache.h +++ b/libs/hwui/ResourceCache.h @@ -20,17 +20,18 @@ #include <cutils/compiler.h> #include <SkBitmap.h> +#include <SkPath.h> #include <utils/KeyedVector.h> #include <utils/Singleton.h> #include <androidfw/ResourceTypes.h> -#include "Layer.h" - namespace android { namespace uirenderer { +class Layer; + /** * Type of Resource being cached */ diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h index 8f19b5c..16ad91d 100644 --- a/libs/hwui/ShadowTessellator.h +++ b/libs/hwui/ShadowTessellator.h @@ -18,14 +18,16 @@ #ifndef ANDROID_HWUI_SHADOW_TESSELLATOR_H #define ANDROID_HWUI_SHADOW_TESSELLATOR_H +#include <SkPath.h> + #include "Debug.h" #include "Matrix.h" -#include "OpenGLRenderer.h" -#include "VertexBuffer.h" namespace android { namespace uirenderer { +class VertexBuffer; + // All SHADOW_* are used to define all the geometry property of shadows. // Use a simplified example to illustrate the geometry setup here. // Assuming we use 6 rays and only 1 layer, Then we will have 2 hexagons, which diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index c672bc4..dff19a9 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -21,6 +21,7 @@ #include <SkMatrix.h> #include "Caches.h" +#include "Extensions.h" #include "Layer.h" #include "Matrix.h" #include "SkiaShader.h" diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 034c3f6..e110ca5 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -24,16 +24,15 @@ #include <cutils/compiler.h> -#include "Extensions.h" -#include "ProgramCache.h" -#include "TextureCache.h" -#include "GradientCache.h" +#include "Matrix.h" namespace android { namespace uirenderer { class Caches; +class Extensions; class Layer; +struct ProgramDescription; /** * Type of Skia shader in use. diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp index 200a9da..001e22f 100644 --- a/libs/hwui/SpotShadow.cpp +++ b/libs/hwui/SpotShadow.cpp @@ -52,6 +52,7 @@ #include "ShadowTessellator.h" #include "SpotShadow.h" #include "Vertex.h" +#include "VertexBuffer.h" #include "utils/MathUtils.h" // TODO: After we settle down the new algorithm, we can remove the old one and diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h index e2d94f7..62a7e5d 100644 --- a/libs/hwui/SpotShadow.h +++ b/libs/hwui/SpotShadow.h @@ -19,11 +19,12 @@ #include "Debug.h" #include "Vector.h" -#include "VertexBuffer.h" namespace android { namespace uirenderer { +class VertexBuffer; + class SpotShadow { public: static void createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter, diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h deleted file mode 100644 index 745e48a..0000000 --- a/libs/hwui/StatefulBaseRenderer.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HWUI_STATEFUL_BASE_RENDERER_H -#define ANDROID_HWUI_STATEFUL_BASE_RENDERER_H - -#include <utils/RefBase.h> - -#include "Renderer.h" -#include "Snapshot.h" - -namespace android { -namespace uirenderer { - -/** - * Abstract Renderer subclass, which implements Canvas state methods. - * - * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the - * Renderer interface. Drawing and recording classes that extend StatefulBaseRenderer 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 - * that quickRejection can also be used. - */ -class StatefulBaseRenderer : public Renderer { -public: - StatefulBaseRenderer(); - - virtual status_t prepare(bool opaque) { - return prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque); - } - - /** - * Initialize 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 - 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); - - // 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); - - virtual void setMatrix(const SkMatrix& matrix); - void setMatrix(const Matrix4& matrix); // internal only convenience method - virtual void concatMatrix(const SkMatrix& matrix); - void concatMatrix(const Matrix4& matrix); // internal only convenience method - - // Clip - virtual const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); } - - virtual bool quickRejectConservative(float left, float top, float right, float bottom) const; - - 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); - - /** - * 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. - */ - 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 - */ - virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}; - - virtual void onViewportInitialized() {}; - - inline const Rect* currentClipRect() const { - return mSnapshot->clipRect; - } - - inline const Snapshot* currentSnapshot() const { - return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get(); - } - - inline const Snapshot* firstSnapshot() const { - return mFirstSnapshot.get(); - } - - // indicites that the clip has been changed since the last time it was consumed - bool mDirtyClip; - -private: - // Dimensions of the drawing surface - int mWidth, mHeight; - - // Number of saved states - int mSaveCount; - - // Base state - sp<Snapshot> mFirstSnapshot; - -protected: - // Current state - // TODO: should become private, once hooks needed by OpenGLRenderer are added - sp<Snapshot> mSnapshot; -}; // class StatefulBaseRenderer - -}; // namespace uirenderer -}; // namespace android - -#endif // ANDROID_HWUI_STATEFUL_BASE_RENDERER_H diff --git a/libs/hwui/TessellationCache.h b/libs/hwui/TessellationCache.h index 688a699..a7c50eb 100644 --- a/libs/hwui/TessellationCache.h +++ b/libs/hwui/TessellationCache.h @@ -24,7 +24,6 @@ #include "Debug.h" #include "utils/Macros.h" #include "utils/Pair.h" -#include "VertexBuffer.h" class SkBitmap; class SkCanvas; @@ -36,6 +35,7 @@ namespace android { namespace uirenderer { class Caches; +class VertexBuffer; /////////////////////////////////////////////////////////////////////////////// // Classes diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp index 4eec462..9e02a30 100644 --- a/libs/hwui/TextDropShadowCache.cpp +++ b/libs/hwui/TextDropShadowCache.cpp @@ -20,6 +20,7 @@ #include "Caches.h" #include "Debug.h" +#include "FontRenderer.h" #include "TextDropShadowCache.h" #include "Properties.h" diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h index 54b930b..bb53a23 100644 --- a/libs/hwui/TextDropShadowCache.h +++ b/libs/hwui/TextDropShadowCache.h @@ -24,13 +24,14 @@ #include <utils/LruCache.h> #include <utils/String16.h> -#include "FontRenderer.h" +#include "font/Font.h" #include "Texture.h" namespace android { namespace uirenderer { class Caches; +class FontRenderer; struct ShadowText { ShadowText(): len(0), radius(0.0f), textSize(0.0f), typeface(NULL), diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 3b8a9a4..0cd120a 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -24,6 +24,7 @@ #include <utils/Mutex.h> #include "Caches.h" +#include "Texture.h" #include "TextureCache.h" #include "Properties.h" diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index 61db5b0..668defc 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -24,11 +24,12 @@ #include <utils/Vector.h> #include "Debug.h" -#include "Texture.h" namespace android { namespace uirenderer { +class Texture; + /////////////////////////////////////////////////////////////////////////////// // Defines /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h index ae6ea94..e820b22 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -20,7 +20,6 @@ #include <utils/Timers.h> -#include "DamageAccumulator.h" #include "utils/Macros.h" namespace android { @@ -30,6 +29,7 @@ namespace renderthread { class CanvasContext; } +class DamageAccumulator; class OpenGLRenderer; class RenderState; diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp index 24ffb80..380c0ed 100644 --- a/libs/hwui/font/CacheTexture.cpp +++ b/libs/hwui/font/CacheTexture.cpp @@ -17,6 +17,7 @@ #include <SkGlyph.h> #include "CacheTexture.h" +#include "FontUtil.h" #include "../Caches.h" #include "../Debug.h" #include "../Extensions.h" diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h index 4cc4f22..a107c7a 100644 --- a/libs/hwui/font/CacheTexture.h +++ b/libs/hwui/font/CacheTexture.h @@ -23,7 +23,6 @@ #include <utils/Log.h> -#include "FontUtil.h" #include "../PixelBuffer.h" #include "../Rect.h" #include "../Vertex.h" diff --git a/libs/hwui/font/CachedGlyphInfo.h b/libs/hwui/font/CachedGlyphInfo.h index 6680a00..0642d59 100644 --- a/libs/hwui/font/CachedGlyphInfo.h +++ b/libs/hwui/font/CachedGlyphInfo.h @@ -19,11 +19,11 @@ #include <SkFixed.h> -#include "CacheTexture.h" - namespace android { namespace uirenderer { +class CacheTexture; + struct CachedGlyphInfo { // Has the cache been invalidated? bool mIsValid; diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp index bf55558..29c122b 100644 --- a/libs/hwui/font/Font.cpp +++ b/libs/hwui/font/Font.cpp @@ -22,6 +22,7 @@ #include <utils/JenkinsHash.h> #include <utils/Trace.h> +#include <SkDeviceProperties.h> #include <SkGlyph.h> #include <SkGlyphCache.h> #include <SkUtils.h> @@ -41,9 +42,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// Font::Font(FontRenderer* state, const Font::FontDescription& desc) : - mState(state), mDescription(desc) { - mDeviceProperties = SkDeviceProperties::Make(SkDeviceProperties::Geometry::MakeDefault(), 1.0f); -} + mState(state), mDescription(desc) { } Font::FontDescription::FontDescription(const SkPaint* paint, const SkMatrix& rasterMatrix) : mLookupTransform(rasterMatrix) { @@ -285,7 +284,8 @@ CachedGlyphInfo* Font::getCachedGlyph(const SkPaint* paint, glyph_t textUnit, bo if (cachedGlyph) { // Is the glyph still in texture cache? if (!cachedGlyph->mIsValid) { - SkAutoGlyphCache autoCache(*paint, &mDeviceProperties, &mDescription.mLookupTransform); + SkDeviceProperties deviceProperties(kUnknown_SkPixelGeometry, 1.0f); + SkAutoGlyphCache autoCache(*paint, &deviceProperties, &mDescription.mLookupTransform); const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), textUnit); updateGlyphCache(paint, skiaGlyph, autoCache.getCache(), cachedGlyph, precaching); } @@ -475,7 +475,8 @@ CachedGlyphInfo* Font::cacheGlyph(const SkPaint* paint, glyph_t glyph, bool prec CachedGlyphInfo* newGlyph = new CachedGlyphInfo(); mCachedGlyphs.add(glyph, newGlyph); - SkAutoGlyphCache autoCache(*paint, &mDeviceProperties, &mDescription.mLookupTransform); + SkDeviceProperties deviceProperties(kUnknown_SkPixelGeometry, 1.0f); + SkAutoGlyphCache autoCache(*paint, &deviceProperties, &mDescription.mLookupTransform); const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), glyph); newGlyph->mIsValid = false; newGlyph->mGlyphIndex = skiaGlyph.fID; diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h index 0f10464..d54bc44 100644 --- a/libs/hwui/font/Font.h +++ b/libs/hwui/font/Font.h @@ -22,13 +22,12 @@ #include <utils/KeyedVector.h> #include <SkScalar.h> -#include <SkDeviceProperties.h> #include <SkGlyphCache.h> #include <SkScalerContext.h> #include <SkPaint.h> #include <SkPathMeasure.h> -#include "CachedGlyphInfo.h" +#include "FontUtil.h" #include "../Rect.h" #include "../Matrix.h" @@ -39,6 +38,8 @@ namespace uirenderer { // Font /////////////////////////////////////////////////////////////////////////////// +class CachedGlyphInfo; +class CacheTexture; class FontRenderer; /** @@ -150,7 +151,6 @@ private: DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs; bool mIdentityTransform; - SkDeviceProperties mDeviceProperties; }; inline int strictly_order_type(const Font::FontDescription& lhs, diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 6c3637d..8299855 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -222,24 +222,23 @@ void CanvasContext::draw() { profiler().unionDirty(&dirty); } - status_t status; if (!dirty.isEmpty()) { - status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop, + mCanvas->prepareDirty(dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom, mOpaque); } else { - status = mCanvas->prepare(mOpaque); + mCanvas->prepare(mOpaque); } Rect outBounds; - status |= mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds); + mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds); profiler().draw(mCanvas); - mCanvas->finish(); + bool drew = mCanvas->finish(); profiler().markPlaybackEnd(); - if (status & DrawGlInfo::kStatusDrew) { + if (drew) { swapBuffers(); } else { mEglManager.cancelFrame(); diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 9bd6f41..e49863d 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -19,6 +19,7 @@ #include <cutils/log.h> #include <cutils/properties.h> +#include "../Caches.h" #include "../RenderState.h" #include "RenderThread.h" |