diff options
Diffstat (limited to 'libs/hwui/DisplayListRenderer.h')
| -rw-r--r-- | libs/hwui/DisplayListRenderer.h | 327 |
1 files changed, 200 insertions, 127 deletions
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 2cc2be3..48ecd69 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -17,12 +17,18 @@ #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 "DisplayListLogBuffer.h" +#include "Canvas.h" +#include "CanvasState.h" +#include "DisplayList.h" +#include "SkiaCanvasProxy.h" #include "RenderNode.h" #include "ResourceCache.h" @@ -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 Canvas, public CanvasStateClient { public: DisplayListRenderer(); virtual ~DisplayListRenderer(); @@ -64,104 +72,178 @@ public: DisplayListData* finishRecording(); // ---------------------------------------------------------------------------- -// Frame state operations +// HWUI Frame state operations // ---------------------------------------------------------------------------- - virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); - virtual void finish(); - virtual void interrupt(); - virtual void resume(); + + void prepareDirty(float left, float top, float right, float bottom); + void prepare() { prepareDirty(0.0f, 0.0f, width(), height()); } + bool finish(); + void interrupt(); + void resume(); // ---------------------------------------------------------------------------- -// Canvas state operations +// HWUI Canvas state operations // ---------------------------------------------------------------------------- - // Save (layer) - virtual int save(int flags); - virtual void restore(); - virtual void restoreToCount(int saveCount); - virtual int saveLayer(float left, float top, float right, float bottom, - const SkPaint* paint, int flags); - - // 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); - - virtual void setMatrix(const SkMatrix& matrix); - virtual void concatMatrix(const SkMatrix& matrix); - // Clip - 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); + void setViewport(int width, int height) { mState.setViewport(width, height); } - // Misc - should be implemented with SkPaint inspection - virtual void resetPaintFilter(); - virtual void setupPaintFilter(int clearBits, int setBits); + const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); } bool isCurrentTransformSimple() { - return currentTransform()->isSimple(); + return mState.currentTransform()->isSimple(); } // ---------------------------------------------------------------------------- -// Canvas draw operations +// HWUI Canvas draw operations // ---------------------------------------------------------------------------- - virtual status_t 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, - 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, - const float* vertices, const int* colors, const SkPaint* paint); - virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, + void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); + // TODO: move drawPatch() to Canvas.h + 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, - 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, - float rx, float ry, const SkPaint* paint); - virtual status_t drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, + void drawRects(const float* rects, int count, const SkPaint* paint); + 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, + void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint); - virtual status_t drawOval(float left, float top, float right, float bottom, - const SkPaint* paint); - virtual status_t 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); - // Text - virtual status_t 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, - float hOffset, float vOffset, const SkPaint* paint); - virtual status_t drawPosText(const char* text, int bytesCount, int count, - const float* positions, const SkPaint* paint); // ---------------------------------------------------------------------------- -// Canvas draw operations - special +// HWUI 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); + void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y); + void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags); // TODO: rename for consistency - virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty); + void callDrawGLFunction(Functor* functor, Rect& dirty); void setHighContrastText(bool highContrastText) { mHighContrastText = highContrastText; } + +// ---------------------------------------------------------------------------- +// CanvasStateClient interface +// ---------------------------------------------------------------------------- + virtual void onViewportInitialized() override { } + virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override { } + virtual GLuint getTargetFbo() const override { return -1; } + +// ---------------------------------------------------------------------------- +// android/graphics/Canvas interface +// ---------------------------------------------------------------------------- + virtual SkCanvas* asSkCanvas() override; + + virtual void setBitmap(SkBitmap* bitmap, bool copyState) override { + LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap."); + } + + virtual bool isOpaque() override { return false; } + virtual int width() override { return mState.getWidth(); } + virtual int height() override { return mState.getHeight(); } + +// ---------------------------------------------------------------------------- +// android/graphics/Canvas state operations +// ---------------------------------------------------------------------------- + // Save (layer) + virtual int getSaveCount() const override { return mState.getSaveCount(); } + virtual int save(SkCanvas::SaveFlags flags) override; + virtual void restore() override; + virtual void restoreToCount(int saveCount) override; + + virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint, + SkCanvas::SaveFlags flags) override; + virtual int saveLayerAlpha(float left, float top, float right, float bottom, + int alpha, SkCanvas::SaveFlags flags) override { + SkPaint paint; + paint.setAlpha(alpha); + return saveLayer(left, top, right, bottom, &paint, flags); + } + + // Matrix + virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); } + virtual void setMatrix(const SkMatrix& matrix) override; + + virtual void concat(const SkMatrix& matrix) override; + virtual void rotate(float degrees) override; + virtual void scale(float sx, float sy) override; + virtual void skew(float sx, float sy) override; + virtual void translate(float dx, float dy) override; + + // Clip + virtual bool getClipBounds(SkRect* outRect) const override; + virtual bool quickRejectRect(float left, float top, float right, float bottom) const override; + virtual bool quickRejectPath(const SkPath& path) const override; + + virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) override; + virtual bool clipPath(const SkPath* path, SkRegion::Op op) override; + virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override; + + // Misc + virtual SkDrawFilter* getDrawFilter() override { return mDrawFilter.get(); } + virtual void setDrawFilter(SkDrawFilter* filter) override; + +// ---------------------------------------------------------------------------- +// android/graphics/Canvas draw operations +// ---------------------------------------------------------------------------- + virtual void drawColor(int color, SkXfermode::Mode mode) override; + virtual void drawPaint(const SkPaint& paint) override; + + // Geometry + virtual void drawPoint(float x, float y, const SkPaint& paint) override { + float points[2] = { x, y }; + drawPoints(points, 2, paint); + } + virtual void drawPoints(const float* points, int count, const SkPaint& paint) override; + virtual void drawLine(float startX, float startY, float stopX, float stopY, + const SkPaint& paint) override { + float points[4] = { startX, startY, stopX, stopY }; + drawLines(points, 4, paint); + } + virtual void drawLines(const float* points, int count, const SkPaint& paint) override; + virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override; + virtual void drawRoundRect(float left, float top, float right, float bottom, + float rx, float ry, const SkPaint& paint) override; + virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override; + virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint) override; + virtual void drawArc(float left, float top, float right, float bottom, + float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) override; + virtual void drawPath(const SkPath& path, const SkPaint& paint) override; + virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount, + const float* verts, const float* tex, const int* colors, + const uint16_t* indices, int indexCount, const SkPaint& paint) override + { /* DisplayListRenderer does not support drawVertices(); ignore */ } + + // Bitmap-based + virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) override; + virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, + const SkPaint* paint) override; + 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) override; + virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight, + const float* vertices, const int* colors, const SkPaint* paint) override; + + // Text + virtual void drawText(const uint16_t* glyphs, const float* positions, int count, + const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, + float boundsRight, float boundsBottom, float totalAdvance) override; + virtual void drawPosText(const uint16_t* text, const float* positions, int count, + int posCount, const SkPaint& paint) override; + virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path, + float hOffset, float vOffset, const SkPaint& paint) override; + virtual bool drawTextAbsolutePos() const override { return false; } + + private: + + CanvasState mState; + std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy; + enum DeferredBarrierType { kBarrier_None, kBarrier_InOrder, @@ -186,7 +268,7 @@ private: template<class T> inline const T* refBuffer(const T* srcBuffer, int32_t count) { - if (!srcBuffer) return NULL; + if (!srcBuffer) return nullptr; T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T)); memcpy(dstBuffer, srcBuffer, count * sizeof(T)); @@ -198,58 +280,51 @@ private: } inline const SkPath* refPath(const SkPath* path) { - if (!path) return NULL; + if (!path) return nullptr; - const SkPath* pathCopy = mPathMap.valueFor(path); - if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { - SkPath* newPathCopy = new SkPath(*path); - newPathCopy->setSourcePath(path); - - pathCopy = newPathCopy; - // replaceValueFor() performs an add if the entry doesn't exist - mPathMap.replaceValueFor(path, pathCopy); - mDisplayListData->paths.add(pathCopy); - } - if (mDisplayListData->sourcePaths.indexOf(path) < 0) { - mResourceCache.incrementRefcount(path); - mDisplayListData->sourcePaths.add(path); - } - return pathCopy; + // The points/verbs within the path are refcounted so this copy operation + // is inexpensive and maintains the generationID of the original path. + const SkPath* cachedPath = new SkPath(*path); + mDisplayListData->pathResources.add(cachedPath); + return cachedPath; } 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 (!paint) return nullptr; + + // 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 == nullptr || *cachedPaint != *paint) { + cachedPaint = new SkPaint(*paint); + std::unique_ptr<const SkPaint> copy(cachedPaint); + mDisplayListData->paints.push_back(std::move(copy)); + // replaceValueFor() performs an add if the entry doesn't exist - mPaintMap.replaceValueFor(paint, paintCopy); + mPaintMap.replaceValueFor(key, 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; + if (!paint) return nullptr; + + SkPaint* returnPaint = new SkPaint(*paint); + std::unique_ptr<const SkPaint> copy(returnPaint); + mDisplayListData->paints.push_back(std::move(copy)); + + return returnPaint; } inline const SkRegion* refRegion(const SkRegion* region) { @@ -257,16 +332,18 @@ private: return region; } - const SkRegion* regionCopy = mRegionMap.valueFor(region); + const SkRegion* cachedRegion = mRegionMap.valueFor(region); // TODO: Add generation ID to SkRegion - if (regionCopy == NULL) { - regionCopy = new SkRegion(*region); + if (cachedRegion == nullptr) { + std::unique_ptr<const SkRegion> copy(new SkRegion(*region)); + cachedRegion = copy.get(); + mDisplayListData->regions.push_back(std::move(copy)); + // replaceValueFor() performs an add if the entry doesn't exist - mRegionMap.replaceValueFor(region, regionCopy); - mDisplayListData->regions.add(regionCopy); + mRegionMap.replaceValueFor(region, cachedRegion); } - return regionCopy; + return cachedRegion; } inline const SkBitmap* refBitmap(const SkBitmap* bitmap) { @@ -274,15 +351,9 @@ private: // correctly, such as creating the bitmap from scratch, drawing with it, changing its // contents, and drawing again. The only fix would be to always copy it the first time, // which doesn't seem worth the extra cycles for this unlikely case. - mDisplayListData->bitmapResources.add(bitmap); - mResourceCache.incrementRefcount(bitmap); - return bitmap; - } - - inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) { - mDisplayListData->ownedBitmapResources.add(bitmap); - mResourceCache.incrementRefcount(bitmap); - return bitmap; + const SkBitmap* cachedBitmap = mResourceCache.insert(bitmap); + mDisplayListData->bitmapResources.add(cachedBitmap); + return cachedBitmap; } inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) { @@ -291,7 +362,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 +377,8 @@ private: int mRestoreSaveCount; + SkAutoTUnref<SkDrawFilter> mDrawFilter; + friend class RenderNode; }; // class DisplayListRenderer |
