diff options
Diffstat (limited to 'libs/hwui/DisplayListCanvas.cpp')
-rw-r--r-- | libs/hwui/DisplayListCanvas.cpp | 187 |
1 files changed, 88 insertions, 99 deletions
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp index 2dd52788074d..f5e57355138c 100644 --- a/libs/hwui/DisplayListCanvas.cpp +++ b/libs/hwui/DisplayListCanvas.cpp @@ -31,70 +31,62 @@ namespace android { namespace uirenderer { -DisplayListCanvas::DisplayListCanvas() +DisplayListCanvas::DisplayListCanvas(int width, int height) : mState(*this) , mResourceCache(ResourceCache::getInstance()) - , mDisplayListData(nullptr) + , mDisplayList(nullptr) , mTranslateX(0.0f) , mTranslateY(0.0f) , mHasDeferredTranslate(false) , mDeferredBarrierType(kBarrier_None) , mHighContrastText(false) , mRestoreSaveCount(-1) { + reset(width, height); } DisplayListCanvas::~DisplayListCanvas() { - LOG_ALWAYS_FATAL_IF(mDisplayListData, + LOG_ALWAYS_FATAL_IF(mDisplayList, "Destroyed a DisplayListCanvas during a record!"); } -/////////////////////////////////////////////////////////////////////////////// -// Operations -/////////////////////////////////////////////////////////////////////////////// - -DisplayListData* DisplayListCanvas::finishRecording() { - mPaintMap.clear(); - mRegionMap.clear(); - mPathMap.clear(); - DisplayListData* data = mDisplayListData; - mDisplayListData = nullptr; - mSkiaCanvasProxy.reset(nullptr); - return data; -} - -void DisplayListCanvas::prepareDirty(float left, float top, - float right, float bottom) { - - LOG_ALWAYS_FATAL_IF(mDisplayListData, +void DisplayListCanvas::reset(int width, int height) { + LOG_ALWAYS_FATAL_IF(mDisplayList, "prepareDirty called a second time during a recording!"); - mDisplayListData = new DisplayListData(); + mDisplayList = new DisplayList(); - mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3()); + mState.initializeSaveStack(width, height, + 0, 0, width, height, Vector3()); mDeferredBarrierType = kBarrier_InOrder; mState.setDirtyClip(false); mRestoreSaveCount = -1; } -bool DisplayListCanvas::finish() { + +/////////////////////////////////////////////////////////////////////////////// +// Operations +/////////////////////////////////////////////////////////////////////////////// + +DisplayList* DisplayListCanvas::finishRecording() { flushRestoreToCount(); flushTranslate(); - return false; -} -void DisplayListCanvas::interrupt() { -} - -void DisplayListCanvas::resume() { + mPaintMap.clear(); + mRegionMap.clear(); + mPathMap.clear(); + DisplayList* displayList = mDisplayList; + mDisplayList = nullptr; + mSkiaCanvasProxy.reset(nullptr); + return displayList; } void DisplayListCanvas::callDrawGLFunction(Functor *functor) { addDrawOp(new (alloc()) DrawFunctorOp(functor)); - mDisplayListData->functors.add(functor); + mDisplayList->functors.push_back(functor); } SkCanvas* DisplayListCanvas::asSkCanvas() { - LOG_ALWAYS_FATAL_IF(!mDisplayListData, + LOG_ALWAYS_FATAL_IF(!mDisplayList, "attempting to get an SkCanvas when we are not recording!"); if (!mSkiaCanvasProxy) { mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this)); @@ -176,11 +168,6 @@ void DisplayListCanvas::setMatrix(const SkMatrix& matrix) { mState.setMatrix(matrix); } -void DisplayListCanvas::setLocalMatrix(const SkMatrix& matrix) { - addStateOp(new (alloc()) SetLocalMatrixOp(matrix)); - mState.setMatrix(matrix); -} - void DisplayListCanvas::concat(const SkMatrix& matrix) { addStateOp(new (alloc()) ConcatMatrixOp(matrix)); mState.concatMatrix(matrix); @@ -229,11 +216,11 @@ void DisplayListCanvas::drawRenderNode(RenderNode* renderNode) { addRenderNodeOp(op); } -void DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) { +void DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle) { // We ref the DeferredLayerUpdater due to its thread-safe ref-counting // semantics. - mDisplayListData->ref(layerHandle); - addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer(), x, y)); + mDisplayList->ref(layerHandle); + addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer())); } void DisplayListCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { @@ -330,13 +317,14 @@ void DisplayListCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, in vertices, colors, paint)); } -void DisplayListCanvas::drawPatch(const SkBitmap& bitmap, const Res_png_9patch* patch, - float left, float top, float right, float bottom, const SkPaint* paint) { +void DisplayListCanvas::drawNinePatch(const SkBitmap& bitmap, const Res_png_9patch& patch, + float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { const SkBitmap* bitmapPtr = refBitmap(bitmap); - patch = refPatch(patch); + const Res_png_9patch* patchPtr = refPatch(&patch); paint = refPaint(paint); - addDrawOp(new (alloc()) DrawPatchOp(bitmapPtr, patch, left, top, right, bottom, paint)); + addDrawOp(new (alloc()) DrawPatchOp(bitmapPtr, patchPtr, + dstLeft, dstTop, dstRight, dstBottom, paint)); } void DisplayListCanvas::drawColor(int color, SkXfermode::Mode mode) { @@ -366,13 +354,13 @@ void DisplayListCanvas::drawRoundRect( CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, CanvasPropertyPaint* paint) { - mDisplayListData->ref(left); - mDisplayListData->ref(top); - mDisplayListData->ref(right); - mDisplayListData->ref(bottom); - mDisplayListData->ref(rx); - mDisplayListData->ref(ry); - mDisplayListData->ref(paint); + mDisplayList->ref(left); + mDisplayList->ref(top); + mDisplayList->ref(right); + mDisplayList->ref(bottom); + mDisplayList->ref(rx); + mDisplayList->ref(ry); + mDisplayList->ref(paint); refBitmapsInShader(paint->value.getShader()); addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value, &right->value, &bottom->value, &rx->value, &ry->value, &paint->value)); @@ -384,10 +372,10 @@ void DisplayListCanvas::drawCircle(float x, float y, float radius, const SkPaint void DisplayListCanvas::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { - mDisplayListData->ref(x); - mDisplayListData->ref(y); - mDisplayListData->ref(radius); - mDisplayListData->ref(paint); + mDisplayList->ref(x); + mDisplayList->ref(y); + mDisplayList->ref(radius); + mDisplayList->ref(paint); refBitmapsInShader(paint->value.getShader()); addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value, &radius->value, &paint->value)); @@ -447,16 +435,6 @@ void DisplayListCanvas::drawPosText(const uint16_t* text, const float* positions addDrawOp(op); } -static void simplifyPaint(int color, SkPaint* paint) { - paint->setColor(color); - paint->setShader(nullptr); - paint->setColorFilter(nullptr); - paint->setLooper(nullptr); - paint->setStrokeWidth(4 + 0.04 * paint->getTextSize()); - paint->setStrokeJoin(SkPaint::kRound_Join); - paint->setLooper(nullptr); -} - void DisplayListCanvas::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, @@ -469,30 +447,34 @@ void DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions, positions = refBuffer<float>(positions, count * 2); Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom); - if (CC_UNLIKELY(mHighContrastText)) { - // high contrast draw path - int color = paint.getColor(); - int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color); - bool darken = channelSum < (128 * 3); - - // outline - SkPaint* outlinePaint = copyPaint(&paint); - simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, outlinePaint); - outlinePaint->setStyle(SkPaint::kStrokeAndFill_Style); - addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, - x, y, positions, outlinePaint, totalAdvance, bounds)); // bounds? - - // inner - SkPaint* innerPaint = copyPaint(&paint); - simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, innerPaint); - innerPaint->setStyle(SkPaint::kFill_Style); - addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, - x, y, positions, innerPaint, totalAdvance, bounds)); + DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, + x, y, positions, refPaint(&paint), totalAdvance, bounds); + addDrawOp(op); +} + +void DisplayListCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { + if (paint.getStyle() != SkPaint::kFill_Style || + (paint.isAntiAlias() && !mState.currentTransform()->isSimple())) { + SkRegion::Iterator it(region); + while (!it.done()) { + const SkIRect& r = it.rect(); + drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint); + it.next(); + } } else { - // standard draw path - DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, - x, y, positions, refPaint(&paint), totalAdvance, bounds); - addDrawOp(op); + int count = 0; + Vector<float> rects; + SkRegion::Iterator it(region); + while (!it.done()) { + const SkIRect& r = it.rect(); + rects.push(r.fLeft); + rects.push(r.fTop); + rects.push(r.fRight); + rects.push(r.fBottom); + count += 4; + it.next(); + } + drawRects(rects.array(), count, &paint); } } @@ -532,21 +514,26 @@ void DisplayListCanvas::flushTranslate() { } size_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) { - int insertIndex = mDisplayListData->displayListOps.add(op); + int insertIndex = mDisplayList->ops.size(); +#if HWUI_NEW_OPS + LOG_ALWAYS_FATAL("unsupported"); +#else + mDisplayList->ops.push_back(op); +#endif if (mDeferredBarrierType != kBarrier_None) { // op is first in new chunk - mDisplayListData->chunks.push(); - DisplayListData::Chunk& newChunk = mDisplayListData->chunks.editTop(); + mDisplayList->chunks.emplace_back(); + DisplayList::Chunk& newChunk = mDisplayList->chunks.back(); newChunk.beginOpIndex = insertIndex; newChunk.endOpIndex = insertIndex + 1; newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder); - int nextChildIndex = mDisplayListData->children().size(); + int nextChildIndex = mDisplayList->children.size(); newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex; mDeferredBarrierType = kBarrier_None; } else { // standard case - append to existing chunk - mDisplayListData->chunks.editTop().endOpIndex = insertIndex + 1; + mDisplayList->chunks.back().endOpIndex = insertIndex + 1; } return insertIndex; } @@ -569,22 +556,24 @@ size_t DisplayListCanvas::addDrawOp(DrawOp* op) { op->setQuickRejected(rejected); } - mDisplayListData->hasDrawOps = true; + mDisplayList->hasDrawOps = true; return flushAndAddOp(op); } size_t DisplayListCanvas::addRenderNodeOp(DrawRenderNodeOp* op) { int opIndex = addDrawOp(op); - int childIndex = mDisplayListData->addChild(op); +#if !HWUI_NEW_OPS + int childIndex = mDisplayList->addChild(op); // update the chunk's child indices - DisplayListData::Chunk& chunk = mDisplayListData->chunks.editTop(); + DisplayList::Chunk& chunk = mDisplayList->chunks.back(); chunk.endChildIndex = childIndex + 1; - if (op->renderNode()->stagingProperties().isProjectionReceiver()) { + if (op->renderNode->stagingProperties().isProjectionReceiver()) { // use staging property, since recording on UI thread - mDisplayListData->projectionReceiveIndex = opIndex; + mDisplayList->projectionReceiveIndex = opIndex; } +#endif return opIndex; } @@ -595,7 +584,7 @@ void DisplayListCanvas::refBitmapsInShader(const SkShader* shader) { // it to the bitmap pile SkBitmap bitmap; SkShader::TileMode xy[2]; - if (shader->asABitmap(&bitmap, nullptr, xy) == SkShader::kDefault_BitmapType) { + if (shader->isABitmap(&bitmap, nullptr, xy)) { refBitmap(bitmap); return; } |