diff options
Diffstat (limited to 'libs/hwui/RecordingCanvas.cpp')
-rw-r--r-- | libs/hwui/RecordingCanvas.cpp | 631 |
1 files changed, 0 insertions, 631 deletions
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp deleted file mode 100644 index e1df1e7725b5..000000000000 --- a/libs/hwui/RecordingCanvas.cpp +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright (C) 2015 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. - */ - -#include "RecordingCanvas.h" - -#include "DeferredLayerUpdater.h" -#include "RecordedOp.h" -#include "RenderNode.h" -#include "VectorDrawable.h" -#include "hwui/MinikinUtils.h" - -namespace android { -namespace uirenderer { - -RecordingCanvas::RecordingCanvas(size_t width, size_t height) - : mState(*this), mResourceCache(ResourceCache::getInstance()) { - resetRecording(width, height); -} - -RecordingCanvas::~RecordingCanvas() { - LOG_ALWAYS_FATAL_IF(mDisplayList, "Destroyed a RecordingCanvas during a record!"); -} - -void RecordingCanvas::resetRecording(int width, int height, RenderNode* node) { - LOG_ALWAYS_FATAL_IF(mDisplayList, "prepareDirty called a second time during a recording!"); - mDisplayList = new DisplayList(); - - mState.initializeRecordingSaveStack(width, height); - - mDeferredBarrierType = DeferredBarrierType::InOrder; -} - -DisplayList* RecordingCanvas::finishRecording() { - restoreToCount(1); - mPaintMap.clear(); - mRegionMap.clear(); - mPathMap.clear(); - DisplayList* displayList = mDisplayList; - mDisplayList = nullptr; - mSkiaCanvasProxy.reset(nullptr); - return displayList; -} - -void RecordingCanvas::insertReorderBarrier(bool enableReorder) { - if (enableReorder) { - mDeferredBarrierType = DeferredBarrierType::OutOfOrder; - mDeferredBarrierClip = getRecordedClip(); - } else { - mDeferredBarrierType = DeferredBarrierType::InOrder; - mDeferredBarrierClip = nullptr; - } -} - -SkCanvas* RecordingCanvas::asSkCanvas() { - LOG_ALWAYS_FATAL_IF(!mDisplayList, "attempting to get an SkCanvas when we are not recording!"); - if (!mSkiaCanvasProxy) { - mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this)); - } - - // SkCanvas instances default to identity transform, but should inherit - // the state of this Canvas; if this code was in the SkiaCanvasProxy - // constructor, we couldn't cache mSkiaCanvasProxy. - SkMatrix parentTransform; - getMatrix(&parentTransform); - mSkiaCanvasProxy.get()->setMatrix(parentTransform); - - return mSkiaCanvasProxy.get(); -} - -// ---------------------------------------------------------------------------- -// CanvasStateClient implementation -// ---------------------------------------------------------------------------- - -void RecordingCanvas::onViewportInitialized() {} - -void RecordingCanvas::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) { - if (removed.flags & Snapshot::kFlagIsFboLayer) { - addOp(alloc().create_trivial<EndLayerOp>()); - } else if (removed.flags & Snapshot::kFlagIsLayer) { - addOp(alloc().create_trivial<EndUnclippedLayerOp>()); - } -} - -// ---------------------------------------------------------------------------- -// android/graphics/Canvas state operations -// ---------------------------------------------------------------------------- -// Save (layer) -int RecordingCanvas::save(SaveFlags::Flags flags) { - return mState.save((int)flags); -} - -void RecordingCanvas::RecordingCanvas::restore() { - mState.restore(); -} - -void RecordingCanvas::restoreToCount(int saveCount) { - mState.restoreToCount(saveCount); -} - -int RecordingCanvas::saveLayer(float left, float top, float right, float bottom, - const SkPaint* paint, SaveFlags::Flags flags) { - // force matrix/clip isolation for layer - flags |= SaveFlags::MatrixClip; - bool clippedLayer = flags & SaveFlags::ClipToLayer; - - const Snapshot& previous = *mState.currentSnapshot(); - - // 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) - - Rect unmappedBounds(left, top, right, bottom); - unmappedBounds.roundOut(); - - // determine clipped bounds relative to previous viewport. - Rect visibleBounds = unmappedBounds; - previous.transform->mapRect(visibleBounds); - - if (CC_UNLIKELY(!clippedLayer && previous.transform->rectToRect() && - visibleBounds.contains(previous.getRenderTargetClip()))) { - // unlikely case where an unclipped savelayer is recorded with a clip it can use, - // as none of its unaffected/unclipped area is visible - clippedLayer = true; - flags |= SaveFlags::ClipToLayer; - } - - visibleBounds.doIntersect(previous.getRenderTargetClip()); - visibleBounds.snapToPixelBoundaries(); - visibleBounds.doIntersect(Rect(previous.getViewportWidth(), previous.getViewportHeight())); - - // Map visible bounds back to layer space, and intersect with parameter bounds - Rect layerBounds = visibleBounds; - if (CC_LIKELY(!layerBounds.isEmpty())) { - // if non-empty, can safely map by the inverse transform - Matrix4 inverse; - inverse.loadInverse(*previous.transform); - inverse.mapRect(layerBounds); - layerBounds.doIntersect(unmappedBounds); - } - - int saveValue = mState.save((int)flags); - Snapshot& snapshot = *mState.writableSnapshot(); - - // layerBounds is in original bounds space, but clipped by current recording clip - if (!layerBounds.isEmpty() && !unmappedBounds.isEmpty()) { - if (CC_LIKELY(clippedLayer)) { - auto previousClip = getRecordedClip(); // capture before new snapshot clip has changed - if (addOp(alloc().create_trivial<BeginLayerOp>( - unmappedBounds, - *previous.transform, // transform to *draw* with - previousClip, // clip to *draw* with - refPaint(paint))) >= 0) { - snapshot.flags |= Snapshot::kFlagIsLayer | Snapshot::kFlagIsFboLayer; - snapshot.initializeViewport(unmappedBounds.getWidth(), unmappedBounds.getHeight()); - snapshot.transform->loadTranslate(-unmappedBounds.left, -unmappedBounds.top, 0.0f); - - Rect clip = layerBounds; - clip.translate(-unmappedBounds.left, -unmappedBounds.top); - snapshot.resetClip(clip.left, clip.top, clip.right, clip.bottom); - snapshot.roundRectClipState = nullptr; - return saveValue; - } - } else { - if (addOp(alloc().create_trivial<BeginUnclippedLayerOp>( - unmappedBounds, *mState.currentSnapshot()->transform, getRecordedClip(), - refPaint(paint))) >= 0) { - snapshot.flags |= Snapshot::kFlagIsLayer; - return saveValue; - } - } - } - - // Layer not needed, so skip recording it... - if (CC_LIKELY(clippedLayer)) { - // ... and set empty clip to reject inner content, if possible - snapshot.resetClip(0, 0, 0, 0); - } - return saveValue; -} - -// Matrix -void RecordingCanvas::rotate(float degrees) { - if (degrees == 0) return; - - mState.rotate(degrees); -} - -void RecordingCanvas::scale(float sx, float sy) { - if (sx == 1 && sy == 1) return; - - mState.scale(sx, sy); -} - -void RecordingCanvas::skew(float sx, float sy) { - mState.skew(sx, sy); -} - -void RecordingCanvas::translate(float dx, float dy) { - if (dx == 0 && dy == 0) return; - - mState.translate(dx, dy, 0); -} - -// Clip -bool RecordingCanvas::getClipBounds(SkRect* outRect) const { - *outRect = mState.getLocalClipBounds().toSkRect(); - return !(outRect->isEmpty()); -} -bool RecordingCanvas::quickRejectRect(float left, float top, float right, float bottom) const { - return mState.quickRejectConservative(left, top, right, bottom); -} -bool RecordingCanvas::quickRejectPath(const SkPath& path) const { - SkRect bounds = path.getBounds(); - return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); -} -bool RecordingCanvas::clipRect(float left, float top, float right, float bottom, SkClipOp op) { - return mState.clipRect(left, top, right, bottom, op); -} -bool RecordingCanvas::clipPath(const SkPath* path, SkClipOp op) { - return mState.clipPath(path, op); -} - -// ---------------------------------------------------------------------------- -// android/graphics/Canvas draw operations -// ---------------------------------------------------------------------------- -void RecordingCanvas::drawColor(int color, SkBlendMode mode) { - addOp(alloc().create_trivial<ColorOp>(getRecordedClip(), color, mode)); -} - -void RecordingCanvas::drawPaint(const SkPaint& paint) { - SkRect bounds; - if (getClipBounds(&bounds)) { - drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint); - } -} - -static Rect calcBoundsOfPoints(const float* points, int floatCount) { - Rect unmappedBounds(points[0], points[1], points[0], points[1]); - for (int i = 2; i < floatCount; i += 2) { - unmappedBounds.expandToCover(points[i], points[i + 1]); - } - return unmappedBounds; -} - -// Geometry -void RecordingCanvas::drawPoints(const float* points, int floatCount, const SkPaint& paint) { - if (CC_UNLIKELY(floatCount < 2 || paint.nothingToDraw())) return; - floatCount &= ~0x1; // round down to nearest two - - addOp(alloc().create_trivial<PointsOp>( - calcBoundsOfPoints(points, floatCount), *mState.currentSnapshot()->transform, - getRecordedClip(), refPaint(&paint), refBuffer<float>(points, floatCount), floatCount)); -} - -void RecordingCanvas::drawLines(const float* points, int floatCount, const SkPaint& paint) { - if (CC_UNLIKELY(floatCount < 4 || paint.nothingToDraw())) return; - floatCount &= ~0x3; // round down to nearest four - - addOp(alloc().create_trivial<LinesOp>( - calcBoundsOfPoints(points, floatCount), *mState.currentSnapshot()->transform, - getRecordedClip(), refPaint(&paint), refBuffer<float>(points, floatCount), floatCount)); -} - -void RecordingCanvas::drawRect(float left, float top, float right, float bottom, - const SkPaint& paint) { - if (CC_UNLIKELY(paint.nothingToDraw())) return; - - addOp(alloc().create_trivial<RectOp>(Rect(left, top, right, bottom), - *(mState.currentSnapshot()->transform), getRecordedClip(), - refPaint(&paint))); -} - -void RecordingCanvas::drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint) { - if (rects == nullptr) return; - - Vertex* rectData = (Vertex*)mDisplayList->allocator.create_trivial_array<Vertex>(vertexCount); - Vertex* vertex = rectData; - - float left = FLT_MAX; - float top = FLT_MAX; - float right = FLT_MIN; - float bottom = FLT_MIN; - for (int index = 0; index < vertexCount; index += 4) { - float l = rects[index + 0]; - float t = rects[index + 1]; - float r = rects[index + 2]; - float b = rects[index + 3]; - - Vertex::set(vertex++, l, t); - Vertex::set(vertex++, r, t); - Vertex::set(vertex++, l, b); - Vertex::set(vertex++, r, b); - - left = std::min(left, l); - top = std::min(top, t); - right = std::max(right, r); - bottom = std::max(bottom, b); - } - addOp(alloc().create_trivial<SimpleRectsOp>( - Rect(left, top, right, bottom), *(mState.currentSnapshot()->transform), - getRecordedClip(), refPaint(paint), rectData, vertexCount)); -} - -void RecordingCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { - if (CC_UNLIKELY(paint.nothingToDraw())) return; - - if (paint.getStyle() == SkPaint::kFill_Style && - (!paint.isAntiAlias() || mState.currentTransform()->isSimple())) { - 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(); - } - drawSimpleRects(rects.array(), count, &paint); - } else { - SkRegion::Iterator it(region); - while (!it.done()) { - const SkIRect& r = it.rect(); - drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint); - it.next(); - } - } -} - -void RecordingCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, - float ry, const SkPaint& paint) { - if (CC_UNLIKELY(paint.nothingToDraw())) return; - - if (CC_LIKELY(MathUtils::isPositive(rx) || MathUtils::isPositive(ry))) { - addOp(alloc().create_trivial<RoundRectOp>(Rect(left, top, right, bottom), - *(mState.currentSnapshot()->transform), - getRecordedClip(), refPaint(&paint), rx, ry)); - } else { - drawRect(left, top, right, bottom, paint); - } -} - -void RecordingCanvas::drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, - CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, - CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, - CanvasPropertyPaint* 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()); - addOp(alloc().create_trivial<RoundRectPropsOp>( - *(mState.currentSnapshot()->transform), getRecordedClip(), &paint->value, &left->value, - &top->value, &right->value, &bottom->value, &rx->value, &ry->value)); -} - -void RecordingCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { - // TODO: move to Canvas.h - if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return; - - drawOval(x - radius, y - radius, x + radius, y + radius, paint); -} - -void RecordingCanvas::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, - CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { - mDisplayList->ref(x); - mDisplayList->ref(y); - mDisplayList->ref(radius); - mDisplayList->ref(paint); - refBitmapsInShader(paint->value.getShader()); - addOp(alloc().create_trivial<CirclePropsOp>(*(mState.currentSnapshot()->transform), - getRecordedClip(), &paint->value, &x->value, - &y->value, &radius->value)); -} - -void RecordingCanvas::drawOval(float left, float top, float right, float bottom, - const SkPaint& paint) { - if (CC_UNLIKELY(paint.nothingToDraw())) return; - - addOp(alloc().create_trivial<OvalOp>(Rect(left, top, right, bottom), - *(mState.currentSnapshot()->transform), getRecordedClip(), - refPaint(&paint))); -} - -void RecordingCanvas::drawArc(float left, float top, float right, float bottom, float startAngle, - float sweepAngle, bool useCenter, const SkPaint& paint) { - if (CC_UNLIKELY(paint.nothingToDraw())) return; - - if (fabs(sweepAngle) >= 360.0f) { - drawOval(left, top, right, bottom, paint); - } else { - addOp(alloc().create_trivial<ArcOp>( - Rect(left, top, right, bottom), *(mState.currentSnapshot()->transform), - getRecordedClip(), refPaint(&paint), startAngle, sweepAngle, useCenter)); - } -} - -void RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) { - if (CC_UNLIKELY(paint.nothingToDraw())) return; - - addOp(alloc().create_trivial<PathOp>(Rect(path.getBounds()), - *(mState.currentSnapshot()->transform), getRecordedClip(), - refPaint(&paint), refPath(&path))); -} - -void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { - mDisplayList->ref(tree); - mDisplayList->vectorDrawables.push_back(tree); - addOp(alloc().create_trivial<VectorDrawableOp>( - tree, Rect(tree->stagingProperties()->getBounds()), - *(mState.currentSnapshot()->transform), getRecordedClip())); -} - -// Bitmap-based -void RecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) { - save(SaveFlags::Matrix); - translate(left, top); - drawBitmap(bitmap, paint); - restore(); -} - -void RecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) { - if (matrix.isIdentity()) { - drawBitmap(bitmap, paint); - } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) && - MathUtils::isPositive(matrix.getScaleX()) && - MathUtils::isPositive(matrix.getScaleY())) { - // SkMatrix::isScaleTranslate() not available in L - SkRect src; - SkRect dst; - bitmap.getBounds(&src); - matrix.mapRect(&dst, src); - drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, dst.fLeft, dst.fTop, - dst.fRight, dst.fBottom, paint); - } else { - save(SaveFlags::Matrix); - concat(matrix); - drawBitmap(bitmap, paint); - restore(); - } -} - -void RecordingCanvas::drawBitmap(Bitmap& 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 && srcRight == bitmap.width() && srcBottom == bitmap.height() && - (srcBottom - srcTop == dstBottom - dstTop) && (srcRight - srcLeft == dstRight - dstLeft)) { - // transform simple rect to rect drawing case into position bitmap ops, since they merge - save(SaveFlags::Matrix); - translate(dstLeft, dstTop); - drawBitmap(bitmap, paint); - restore(); - } else { - addOp(alloc().create_trivial<BitmapRectOp>( - Rect(dstLeft, dstTop, dstRight, dstBottom), *(mState.currentSnapshot()->transform), - getRecordedClip(), refPaint(paint), refBitmap(bitmap), - Rect(srcLeft, srcTop, srcRight, srcBottom))); - } -} - -void RecordingCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight, - const float* vertices, const int* colors, - const SkPaint* paint) { - int vertexCount = (meshWidth + 1) * (meshHeight + 1); - addOp(alloc().create_trivial<BitmapMeshOp>( - calcBoundsOfPoints(vertices, vertexCount * 2), *(mState.currentSnapshot()->transform), - getRecordedClip(), refPaint(paint), refBitmap(bitmap), meshWidth, meshHeight, - refBuffer<float>(vertices, vertexCount * 2), // 2 floats per vertex - refBuffer<int>(colors, vertexCount))); // 1 color per vertex -} - -void RecordingCanvas::drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& patch, - float dstLeft, float dstTop, float dstRight, float dstBottom, - const SkPaint* paint) { - addOp(alloc().create_trivial<PatchOp>(Rect(dstLeft, dstTop, dstRight, dstBottom), - *(mState.currentSnapshot()->transform), getRecordedClip(), - refPaint(paint), refBitmap(bitmap), refPatch(&patch))); -} - -double RecordingCanvas::drawAnimatedImage(AnimatedImageDrawable*) { - // Unimplemented - return 0; -} - -// Text -void RecordingCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int glyphCount, const SkPaint& paint, - float x, float y, float boundsLeft, float boundsTop, - float boundsRight, float boundsBottom, float totalAdvance) { - if (glyphCount <= 0 || paint.nothingToDraw()) return; - uint16_t* glyphs = (glyph_t*)alloc().alloc<glyph_t>(glyphCount * sizeof(glyph_t)); - float* positions = (float*)alloc().alloc<float>(2 * glyphCount * sizeof(float)); - glyphFunc(glyphs, positions); - - // TODO: either must account for text shadow in bounds, or record separate ops for text shadows - addOp(alloc().create_trivial<TextOp>(Rect(boundsLeft, boundsTop, boundsRight, boundsBottom), - *(mState.currentSnapshot()->transform), getRecordedClip(), - refPaint(&paint), glyphs, positions, glyphCount, x, y)); - drawTextDecorations(x, y, totalAdvance, paint); -} - -void RecordingCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset, - const SkPaint& paint, const SkPath& path, size_t start, - size_t end) { - uint16_t glyphs[1]; - for (size_t i = start; i < end; i++) { - glyphs[0] = layout.getGlyphId(i); - float x = hOffset + layout.getX(i); - float y = vOffset + layout.getY(i); - if (paint.nothingToDraw()) return; - const uint16_t* tempGlyphs = refBuffer<glyph_t>(glyphs, 1); - addOp(alloc().create_trivial<TextOnPathOp>(*(mState.currentSnapshot()->transform), - getRecordedClip(), refPaint(&paint), tempGlyphs, - 1, refPath(&path), x, y)); - } -} - -void RecordingCanvas::drawBitmap(Bitmap& bitmap, const SkPaint* paint) { - addOp(alloc().create_trivial<BitmapOp>(Rect(bitmap.width(), bitmap.height()), - *(mState.currentSnapshot()->transform), - getRecordedClip(), refPaint(paint), refBitmap(bitmap))); -} - -void RecordingCanvas::drawRenderNode(RenderNode* renderNode) { - auto&& stagingProps = renderNode->stagingProperties(); - RenderNodeOp* op = alloc().create_trivial<RenderNodeOp>( - Rect(stagingProps.getWidth(), stagingProps.getHeight()), - *(mState.currentSnapshot()->transform), getRecordedClip(), renderNode); - int opIndex = addOp(op); - if (CC_LIKELY(opIndex >= 0)) { - int childIndex = mDisplayList->addChild(op); - - // update the chunk's child indices - DisplayList::Chunk& chunk = mDisplayList->chunks.back(); - chunk.endChildIndex = childIndex + 1; - - if (renderNode->stagingProperties().isProjectionReceiver()) { - // use staging property, since recording on UI thread - mDisplayList->projectionReceiveIndex = opIndex; - } - } -} - -void RecordingCanvas::drawLayer(DeferredLayerUpdater* layerHandle) { - // We ref the DeferredLayerUpdater due to its thread-safe ref-counting semantics. - mDisplayList->ref(layerHandle); - - LOG_ALWAYS_FATAL_IF(layerHandle->getBackingLayerApi() != Layer::Api::OpenGL); - // Note that the backing layer has *not* yet been updated, so don't trust - // its width, height, transform, etc...! - addOp(alloc().create_trivial<TextureLayerOp>( - Rect(layerHandle->getWidth(), layerHandle->getHeight()), - *(mState.currentSnapshot()->transform), getRecordedClip(), layerHandle)); -} - -void RecordingCanvas::callDrawGLFunction(Functor* functor, GlFunctorLifecycleListener* listener) { - mDisplayList->functors.push_back({functor, listener}); - mDisplayList->ref(listener); - addOp(alloc().create_trivial<FunctorOp>(*(mState.currentSnapshot()->transform), - getRecordedClip(), functor)); -} - -int RecordingCanvas::addOp(RecordedOp* op) { - // skip op with empty clip - if (op->localClip && op->localClip->rect.isEmpty()) { - // NOTE: this rejection happens after op construction/content ref-ing, so content ref'd - // and held by renderthread isn't affected by clip rejection. - // Could rewind alloc here if desired, but callers would have to not touch op afterwards. - return -1; - } - - int insertIndex = mDisplayList->ops.size(); - mDisplayList->ops.push_back(op); - if (mDeferredBarrierType != DeferredBarrierType::None) { - // op is first in new chunk - mDisplayList->chunks.emplace_back(); - DisplayList::Chunk& newChunk = mDisplayList->chunks.back(); - newChunk.beginOpIndex = insertIndex; - newChunk.endOpIndex = insertIndex + 1; - newChunk.reorderChildren = (mDeferredBarrierType == DeferredBarrierType::OutOfOrder); - newChunk.reorderClip = mDeferredBarrierClip; - - int nextChildIndex = mDisplayList->children.size(); - newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex; - mDeferredBarrierType = DeferredBarrierType::None; - } else { - // standard case - append to existing chunk - mDisplayList->chunks.back().endOpIndex = insertIndex + 1; - } - return insertIndex; -} - -void RecordingCanvas::refBitmapsInShader(const SkShader* shader) { - if (!shader) return; - - // If this paint has an SkShader that has an SkBitmap add - // it to the bitmap pile - SkBitmap bitmap; - SkShader::TileMode xy[2]; - if (shader->isABitmap(&bitmap, nullptr, xy)) { - Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef()); - refBitmap(*hwuiBitmap); - return; - } - SkShader::ComposeRec rec; - if (shader->asACompose(&rec)) { - refBitmapsInShader(rec.fShaderA); - refBitmapsInShader(rec.fShaderB); - return; - } -} - -}; // namespace uirenderer -}; // namespace android |