diff options
Diffstat (limited to 'libs/hwui/DisplayListRenderer.cpp')
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 250 |
1 files changed, 94 insertions, 156 deletions
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 8866029..2391e80 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -21,120 +21,58 @@ #include <private/hwui/DrawGlInfo.h> -#include "DisplayList.h" +#include "Caches.h" #include "DeferredDisplayList.h" #include "DisplayListLogBuffer.h" #include "DisplayListOp.h" #include "DisplayListRenderer.h" -#include "Caches.h" +#include "RenderNode.h" namespace android { namespace uirenderer { DisplayListRenderer::DisplayListRenderer(): - mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData), + mCaches(Caches::getInstance()), mDisplayListData(0), mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), - mHasDrawOps(false), mFunctorCount(0) { + mRestoreSaveCount(-1) { } DisplayListRenderer::~DisplayListRenderer() { - reset(); + LOG_ALWAYS_FATAL_IF(mDisplayListData, + "Destroyed a DisplayListRenderer during a record!"); } -void DisplayListRenderer::reset() { - mDisplayListData = new DisplayListData(); - mCaches.resourceCache.lock(); - - for (size_t i = 0; i < mBitmapResources.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); - } - - for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i)); - } - - for (size_t i = 0; i < mFilterResources.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i)); - } - - for (size_t i = 0; i < mPatchResources.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mPatchResources.itemAt(i)); - } - - for (size_t i = 0; i < mShaders.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); - } - - for (size_t i = 0; i < mSourcePaths.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); - } - - for (size_t i = 0; i < mLayers.size(); i++) { - mCaches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i)); - } - - mCaches.resourceCache.unlock(); - - mBitmapResources.clear(); - mOwnedBitmapResources.clear(); - mFilterResources.clear(); - mPatchResources.clear(); - mSourcePaths.clear(); +/////////////////////////////////////////////////////////////////////////////// +// Operations +/////////////////////////////////////////////////////////////////////////////// - mShaders.clear(); +DisplayListData* DisplayListRenderer::finishRecording() { mShaderMap.clear(); - - mPaints.clear(); mPaintMap.clear(); - - mRegions.clear(); mRegionMap.clear(); - - mPaths.clear(); mPathMap.clear(); - - mMatrices.clear(); - - mLayers.clear(); - - mHasDrawOps = false; - mFunctorCount = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Operations -/////////////////////////////////////////////////////////////////////////////// - -DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) { - if (!displayList) { - displayList = new DisplayList(*this); - } else { - displayList->initFromDisplayListRenderer(*this, true); - } - displayList->setRenderable(mHasDrawOps); - return displayList; -} - -bool DisplayListRenderer::isDeferred() { - return true; + DisplayListData* data = mDisplayListData; + mDisplayListData = 0; + return data; } void DisplayListRenderer::setViewport(int width, int height) { - mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); + // TODO: DisplayListRenderer shouldn't have a projection matrix, as it should never be used + mProjectionMatrix.loadOrtho(0, width, height, 0, -1, 1); - mWidth = width; - mHeight = height; + initializeViewport(width, height); } status_t DisplayListRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { - mSnapshot = new Snapshot(mFirstSnapshot, - SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); - mSaveCount = 1; - mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); - mDirtyClip = opaque; + LOG_ALWAYS_FATAL_IF(mDisplayListData, + "prepareDirty called a second time during a recording!"); + mDisplayListData = new DisplayListData(); + initializeSaveStack(0, 0, getWidth(), getHeight()); + + mDirtyClip = opaque; mRestoreSaveCount = -1; return DrawGlInfo::kStatusDone; // No invalidate needed at record-time @@ -154,13 +92,13 @@ void DisplayListRenderer::resume() { status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { // Ignore dirty during recording, it matters only when we replay addDrawOp(new (alloc()) DrawFunctorOp(functor)); - mFunctorCount++; + mDisplayListData->functorCount++; return DrawGlInfo::kStatusDone; // No invalidate needed at record-time } int DisplayListRenderer::save(int flags) { addStateOp(new (alloc()) SaveOp(flags)); - return OpenGLRenderer::save(flags); + return StatefulBaseRenderer::save(flags); } void DisplayListRenderer::restore() { @@ -171,84 +109,90 @@ void DisplayListRenderer::restore() { mRestoreSaveCount--; insertTranslate(); - OpenGLRenderer::restore(); + StatefulBaseRenderer::restore(); } void DisplayListRenderer::restoreToCount(int saveCount) { mRestoreSaveCount = saveCount; insertTranslate(); - OpenGLRenderer::restoreToCount(saveCount); + StatefulBaseRenderer::restoreToCount(saveCount); } int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, - int alpha, SkXfermode::Mode mode, int flags) { - addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, alpha, mode, flags)); - return OpenGLRenderer::save(flags); + const SkPaint* paint, int flags) { + paint = refPaint(paint); + addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags)); + return StatefulBaseRenderer::save(flags); } -void DisplayListRenderer::translate(float dx, float dy) { +void DisplayListRenderer::translate(float dx, float dy, float dz) { + // ignore dz, not used at defer time mHasTranslate = true; mTranslateX += dx; mTranslateY += dy; insertRestoreToCount(); - OpenGLRenderer::translate(dx, dy); + StatefulBaseRenderer::translate(dx, dy, dz); } void DisplayListRenderer::rotate(float degrees) { addStateOp(new (alloc()) RotateOp(degrees)); - OpenGLRenderer::rotate(degrees); + StatefulBaseRenderer::rotate(degrees); } void DisplayListRenderer::scale(float sx, float sy) { addStateOp(new (alloc()) ScaleOp(sx, sy)); - OpenGLRenderer::scale(sx, sy); + StatefulBaseRenderer::scale(sx, sy); } void DisplayListRenderer::skew(float sx, float sy) { addStateOp(new (alloc()) SkewOp(sx, sy)); - OpenGLRenderer::skew(sx, sy); + StatefulBaseRenderer::skew(sx, sy); } -void DisplayListRenderer::setMatrix(SkMatrix* matrix) { +void DisplayListRenderer::setMatrix(const SkMatrix* matrix) { matrix = refMatrix(matrix); addStateOp(new (alloc()) SetMatrixOp(matrix)); - OpenGLRenderer::setMatrix(matrix); + StatefulBaseRenderer::setMatrix(matrix); } -void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { +void DisplayListRenderer::concatMatrix(const SkMatrix* matrix) { matrix = refMatrix(matrix); addStateOp(new (alloc()) ConcatMatrixOp(matrix)); - OpenGLRenderer::concatMatrix(matrix); + StatefulBaseRenderer::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 OpenGLRenderer::clipRect(left, top, right, bottom, op); + return StatefulBaseRenderer::clipRect(left, top, right, bottom, op); } -bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) { +bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) { path = refPath(path); addStateOp(new (alloc()) ClipPathOp(path, op)); - return OpenGLRenderer::clipPath(path, op); + return StatefulBaseRenderer::clipPath(path, op); } -bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) { +bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { region = refRegion(region); addStateOp(new (alloc()) ClipRegionOp(region, op)); - return OpenGLRenderer::clipRegion(region, op); + return StatefulBaseRenderer::clipRegion(region, op); } -status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList, +status_t DisplayListRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty, int32_t flags) { // dirty is an out parameter and should not be recorded, // it matters only when replaying the display list - // TODO: To be safe, the display list should be ref-counted in the - // resources cache, but we rely on the caller (UI toolkit) to - // do the right thing for now + if (displayList->stagingProperties().isProjectionReceiver()) { + // use staging property, since recording on UI thread + mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size(); + } - addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags)); + DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList, + flags, *currentTransform()); + addDrawOp(op); + mDisplayListData->addChild(op); return DrawGlInfo::kStatusDone; } @@ -258,7 +202,8 @@ status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) { return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { +status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top, + const SkPaint* paint) { bitmap = refBitmap(bitmap); paint = refPaint(paint); @@ -266,7 +211,8 @@ status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { +status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix, + const SkPaint* paint) { bitmap = refBitmap(bitmap); matrix = refMatrix(matrix); paint = refPaint(paint); @@ -275,9 +221,9 @@ status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkP return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, +status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, - float dstRight, float dstBottom, SkPaint* paint) { + float dstRight, float dstBottom, const SkPaint* paint) { bitmap = refBitmap(bitmap); paint = refPaint(paint); @@ -296,8 +242,8 @@ status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, - SkPaint* paint) { +status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top, + const SkPaint* paint) { bitmap = refBitmapData(bitmap); paint = refPaint(paint); @@ -305,21 +251,21 @@ status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, - float* vertices, int* colors, SkPaint* paint) { - int count = (meshWidth + 1) * (meshHeight + 1) * 2; +status_t 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); - vertices = refBuffer<float>(vertices, count); + vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex paint = refPaint(paint); - colors = refBuffer<int>(colors, count); + colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, vertices, colors, paint)); return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, - float left, float top, float right, float bottom, SkPaint* paint) { +status_t 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); @@ -334,41 +280,52 @@ status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { } status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, - SkPaint* paint) { + 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, - float rx, float ry, SkPaint* paint) { + 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::drawCircle(float x, float y, float radius, SkPaint* paint) { +status_t 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, + CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { + mDisplayListData->refProperty(x); + mDisplayListData->refProperty(y); + mDisplayListData->refProperty(radius); + mDisplayListData->refProperty(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, - SkPaint* paint) { + 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, - float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { + float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) { paint = refPaint(paint); addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint)); return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { +status_t DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) { path = refPath(path); paint = refPaint(paint); @@ -376,7 +333,7 @@ status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { +status_t DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) { points = refBuffer<float>(points, count); paint = refPaint(paint); @@ -384,7 +341,7 @@ status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { +status_t DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { points = refBuffer<float>(points, count); paint = refPaint(paint); @@ -393,7 +350,7 @@ status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* pain } status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, - SkPath* path, float hOffset, float vOffset, SkPaint* paint) { + const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; text = refText(text, bytesCount); @@ -407,7 +364,7 @@ status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, i } status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, - const float* positions, SkPaint* paint) { + const float* positions, const SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; text = refText(text, bytesCount); @@ -420,7 +377,7 @@ status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int } status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, - float x, float y, const float* positions, SkPaint* paint, + float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; @@ -435,7 +392,7 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou return DrawGlInfo::kStatusDone; } -status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) { +status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { if (count <= 0) return DrawGlInfo::kStatusDone; rects = refBuffer<float>(rects, count); @@ -453,25 +410,6 @@ void DisplayListRenderer::setupShader(SkiaShader* shader) { addStateOp(new (alloc()) SetupShaderOp(shader)); } -void DisplayListRenderer::resetColorFilter() { - addStateOp(new (alloc()) ResetColorFilterOp()); -} - -void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { - filter = refColorFilter(filter); - addStateOp(new (alloc()) SetupColorFilterOp(filter)); -} - -void DisplayListRenderer::resetShadow() { - addStateOp(new (alloc()) ResetShadowOp()); - OpenGLRenderer::resetShadow(); -} - -void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { - addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color)); - OpenGLRenderer::setupShadow(radius, dx, dy, color); -} - void DisplayListRenderer::resetPaintFilter() { addStateOp(new (alloc()) ResetPaintFilterOp()); } @@ -506,12 +444,12 @@ void DisplayListRenderer::addStateOp(StateOp* op) { void DisplayListRenderer::addDrawOp(DrawOp* op) { Rect localBounds; if (op->getLocalBounds(mDrawModifiers, localBounds)) { - bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top, + bool rejected = quickRejectConservative(localBounds.left, localBounds.top, localBounds.right, localBounds.bottom); op->setQuickRejected(rejected); } - mHasDrawOps = true; + mDisplayListData->hasDrawOps = true; addOpInternal(op); } |