Loading libs/hwui/BakedOpDispatcher.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -309,6 +309,14 @@ void BakedOpDispatcher::onEndLayerOp(BakedOpRenderer&, const EndLayerOp&, const LOG_ALWAYS_FATAL("unsupported operation"); } void BakedOpDispatcher::onCirclePropsOp(BakedOpRenderer&, const CirclePropsOp&, const BakedOpState&) { LOG_ALWAYS_FATAL("unsupported operation"); } void BakedOpDispatcher::onRoundRectPropsOp(BakedOpRenderer&, const RoundRectPropsOp&, const BakedOpState&) { LOG_ALWAYS_FATAL("unsupported operation"); } namespace VertexBufferRenderFlags { enum { Offset = 0x1, Loading libs/hwui/OpReorderer.cpp +60 −34 Original line number Diff line number Diff line Loading @@ -467,13 +467,13 @@ void OpReorderer::deferNodePropsAndOps(RenderNode& node) { // (temp layers are clipped to viewport, since they don't persist offscreen content) SkPaint saveLayerPaint; saveLayerPaint.setAlpha(properties.getAlpha()); onBeginLayerOp(*new (mAllocator) BeginLayerOp( deferBeginLayerOp(*new (mAllocator) BeginLayerOp( saveLayerBounds, Matrix4::identity(), saveLayerBounds, &saveLayerPaint)); deferNodeOps(node); onEndLayerOp(*new (mAllocator) EndLayerOp()); deferEndLayerOp(*new (mAllocator) EndLayerOp()); } else { deferNodeOps(node); } Loading Loading @@ -559,7 +559,7 @@ void OpReorderer::defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedN } const RenderNodeOp* childOp = zTranslatedNodes[drawIndex].value; deferRenderNodeOp(*childOp); deferRenderNodeOpImpl(*childOp); drawIndex++; } } Loading Loading @@ -645,7 +645,7 @@ void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) { int restoreTo = mCanvasState.save(SkCanvas::kMatrix_SaveFlag); mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor); deferRenderNodeOp(*childOp); deferRenderNodeOpImpl(*childOp); mCanvasState.restoreToCount(restoreTo); } Loading @@ -653,13 +653,13 @@ void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) { } /** * Used to define a list of lambdas referencing private OpReorderer::onXXXXOp() methods. * Used to define a list of lambdas referencing private OpReorderer::onXX::defer() methods. * * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas. * E.g. a BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&) */ #define OP_RECEIVER(Type) \ [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.on##Type(static_cast<const Type&>(op)); }, [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.defer##Type(static_cast<const Type&>(op)); }, void OpReorderer::deferNodeOps(const RenderNode& renderNode) { typedef void (*OpDispatcher) (OpReorderer& reorderer, const RecordedOp& op); static OpDispatcher receivers[] = { Loading Loading @@ -687,7 +687,7 @@ void OpReorderer::deferNodeOps(const RenderNode& renderNode) { } } void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) { void OpReorderer::deferRenderNodeOpImpl(const RenderNodeOp& op) { if (op.renderNode->nothingToDraw()) return; int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); Loading @@ -702,9 +702,9 @@ void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) { mCanvasState.restoreToCount(count); } void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) { void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) { if (!op.skipInOrderDraw) { deferRenderNodeOp(op); deferRenderNodeOpImpl(op); } } Loading @@ -712,7 +712,7 @@ void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) { * Defers an unmergeable, strokeable op, accounting correctly * for paint's style on the bounds being computed. */ void OpReorderer::onStrokeableOp(const RecordedOp& op, batchid_t batchId, void OpReorderer::deferStrokeableOp(const RecordedOp& op, batchid_t batchId, BakedOpState::StrokeBehavior strokeBehavior) { // Note: here we account for stroke when baking the op BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct( Loading @@ -734,11 +734,11 @@ static batchid_t tessBatchId(const RecordedOp& op) { : (paint.isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices); } void OpReorderer::onArcOp(const ArcOp& op) { onStrokeableOp(op, tessBatchId(op)); void OpReorderer::deferArcOp(const ArcOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void OpReorderer::onBitmapOp(const BitmapOp& op) { void OpReorderer::deferBitmapOp(const BitmapOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -757,28 +757,43 @@ void OpReorderer::onBitmapOp(const BitmapOp& op) { } } void OpReorderer::onBitmapMeshOp(const BitmapMeshOp& op) { void OpReorderer::deferBitmapMeshOp(const BitmapMeshOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap); } void OpReorderer::onBitmapRectOp(const BitmapRectOp& op) { void OpReorderer::deferBitmapRectOp(const BitmapRectOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap); } void OpReorderer::onLinesOp(const LinesOp& op) { void OpReorderer::deferCirclePropsOp(const CirclePropsOp& op) { // allocate a temporary oval op (with mAllocator, so it persists until render), so the // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple. float x = *(op.x); float y = *(op.y); float radius = *(op.radius); Rect unmappedBounds(x - radius, y - radius, x + radius, y + radius); const OvalOp* resolvedOp = new (mAllocator) OvalOp( unmappedBounds, op.localMatrix, op.localClipRect, op.paint); deferOvalOp(*resolvedOp); } void OpReorderer::deferLinesOp(const LinesOp& op) { batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices; onStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); } void OpReorderer::onOvalOp(const OvalOp& op) { onStrokeableOp(op, tessBatchId(op)); void OpReorderer::deferOvalOp(const OvalOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void OpReorderer::onPatchOp(const PatchOp& op) { void OpReorderer::deferPatchOp(const PatchOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -795,30 +810,41 @@ void OpReorderer::onPatchOp(const PatchOp& op) { } } void OpReorderer::onPathOp(const PathOp& op) { onStrokeableOp(op, OpBatchType::Bitmap); void OpReorderer::deferPathOp(const PathOp& op) { deferStrokeableOp(op, OpBatchType::Bitmap); } void OpReorderer::onPointsOp(const PointsOp& op) { void OpReorderer::deferPointsOp(const PointsOp& op) { batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices; onStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); } void OpReorderer::deferRectOp(const RectOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void OpReorderer::onRectOp(const RectOp& op) { onStrokeableOp(op, tessBatchId(op)); void OpReorderer::deferRoundRectOp(const RoundRectOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void OpReorderer::onRoundRectOp(const RoundRectOp& op) { onStrokeableOp(op, tessBatchId(op)); void OpReorderer::deferRoundRectPropsOp(const RoundRectPropsOp& op) { // allocate a temporary round rect op (with mAllocator, so it persists until render), so the // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple. const RoundRectOp* resolvedOp = new (mAllocator) RoundRectOp( Rect(*(op.left), *(op.top), *(op.right), *(op.bottom)), op.localMatrix, op.localClipRect, op.paint, *op.rx, *op.ry); deferRoundRectOp(*resolvedOp); } void OpReorderer::onSimpleRectsOp(const SimpleRectsOp& op) { void OpReorderer::deferSimpleRectsOp(const SimpleRectsOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices); } void OpReorderer::onTextOp(const TextOp& op) { void OpReorderer::deferTextOp(const TextOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading Loading @@ -861,7 +887,7 @@ void OpReorderer::restoreForLayer() { } // TODO: test rejection at defer time, where the bounds become empty void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) { void OpReorderer::deferBeginLayerOp(const BeginLayerOp& op) { uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth(); uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight(); Loading Loading @@ -906,7 +932,7 @@ void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) { &op, nullptr); } void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) { void OpReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) { const BeginLayerOp& beginLayerOp = *currentLayer().beginLayerOp; int finishedLayerIndex = mLayerStack.back(); Loading @@ -932,11 +958,11 @@ void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) { } } void OpReorderer::onLayerOp(const LayerOp& op) { void OpReorderer::deferLayerOp(const LayerOp& op) { LOG_ALWAYS_FATAL("unsupported"); } void OpReorderer::onShadowOp(const ShadowOp& op) { void OpReorderer::deferShadowOp(const ShadowOp& op) { LOG_ALWAYS_FATAL("unsupported"); } Loading libs/hwui/OpReorderer.h +4 −4 Original line number Diff line number Diff line Loading @@ -237,7 +237,7 @@ private: void deferNodeOps(const RenderNode& renderNode); void deferRenderNodeOp(const RenderNodeOp& op); void deferRenderNodeOpImpl(const RenderNodeOp& op); void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers); Loading @@ -246,17 +246,17 @@ private: return mFrameAllocatedPaths.back().get(); } void onStrokeableOp(const RecordedOp& op, batchid_t batchId, void deferStrokeableOp(const RecordedOp& op, batchid_t batchId, BakedOpState::StrokeBehavior strokeBehavior = BakedOpState::StrokeBehavior::StyleDefined); /** * Declares all OpReorderer::onXXXXOp() methods for every RecordedOp type. * Declares all OpReorderer::deferXXXXOp() methods for every RecordedOp type. * * These private methods are called from within deferImpl to defer each individual op * type differently. */ #define INTERNAL_OP_HANDLER(Type) \ void on##Type(const Type& op); void defer##Type(const Type& op); MAP_OPS(INTERNAL_OP_HANDLER) std::vector<std::unique_ptr<SkPath> > mFrameAllocatedPaths; Loading libs/hwui/RecordedOp.h +32 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ struct Vertex; M_OP_FN(BitmapOp) \ U_OP_FN(BitmapMeshOp) \ U_OP_FN(BitmapRectOp) \ U_OP_FN(CirclePropsOp) \ U_OP_FN(LinesOp) \ U_OP_FN(OvalOp) \ M_OP_FN(PatchOp) \ Loading @@ -56,6 +57,7 @@ struct Vertex; U_OP_FN(RectOp) \ U_OP_FN(RenderNodeOp) \ U_OP_FN(RoundRectOp) \ U_OP_FN(RoundRectPropsOp) \ U_OP_FN(ShadowOp) \ U_OP_FN(SimpleRectsOp) \ M_OP_FN(TextOp) \ Loading Loading @@ -181,6 +183,18 @@ struct BitmapRectOp : RecordedOp { const Rect src; }; struct CirclePropsOp : RecordedOp { CirclePropsOp(const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint, float* x, float* y, float* radius) : RecordedOp(RecordedOpId::CirclePropsOp, Rect(), localMatrix, localClipRect, paint) , x(x) , y(y) , radius(radius) {} const float* x; const float* y; const float* radius; }; struct LinesOp : RecordedOp { LinesOp(BASE_PARAMS, const float* points, const int floatCount) : SUPER(LinesOp) Loading @@ -195,7 +209,6 @@ struct OvalOp : RecordedOp { : SUPER(OvalOp) {} }; struct PatchOp : RecordedOp { PatchOp(BASE_PARAMS, const SkBitmap* bitmap, const Res_png_9patch* patch) : SUPER(PatchOp) Loading Loading @@ -235,6 +248,24 @@ struct RoundRectOp : RecordedOp { const float ry; }; struct RoundRectPropsOp : RecordedOp { RoundRectPropsOp(const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint, float* left, float* top, float* right, float* bottom, float *rx, float *ry) : RecordedOp(RecordedOpId::RoundRectPropsOp, Rect(), localMatrix, localClipRect, paint) , left(left) , top(top) , right(right) , bottom(bottom) , rx(rx) , ry(ry) {} const float* left; const float* top; const float* right; const float* bottom; const float* rx; const float* ry; }; /** * Real-time, dynamic-lit shadow. * Loading libs/hwui/RecordingCanvas.cpp +38 −0 Original line number Diff line number Diff line Loading @@ -343,11 +343,49 @@ void RecordingCanvas::drawRoundRect(float left, float top, float right, float bo refPaint(&paint), rx, ry)); } 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(new (alloc()) RoundRectPropsOp( *(mState.currentSnapshot()->transform), mState.getRenderTargetClipBounds(), &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 (radius <= 0) 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(new (alloc()) CirclePropsOp( *(mState.currentSnapshot()->transform), mState.getRenderTargetClipBounds(), &paint->value, &x->value, &y->value, &radius->value)); } void RecordingCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) { addOp(new (alloc()) OvalOp( Rect(left, top, right, bottom), Loading Loading
libs/hwui/BakedOpDispatcher.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -309,6 +309,14 @@ void BakedOpDispatcher::onEndLayerOp(BakedOpRenderer&, const EndLayerOp&, const LOG_ALWAYS_FATAL("unsupported operation"); } void BakedOpDispatcher::onCirclePropsOp(BakedOpRenderer&, const CirclePropsOp&, const BakedOpState&) { LOG_ALWAYS_FATAL("unsupported operation"); } void BakedOpDispatcher::onRoundRectPropsOp(BakedOpRenderer&, const RoundRectPropsOp&, const BakedOpState&) { LOG_ALWAYS_FATAL("unsupported operation"); } namespace VertexBufferRenderFlags { enum { Offset = 0x1, Loading
libs/hwui/OpReorderer.cpp +60 −34 Original line number Diff line number Diff line Loading @@ -467,13 +467,13 @@ void OpReorderer::deferNodePropsAndOps(RenderNode& node) { // (temp layers are clipped to viewport, since they don't persist offscreen content) SkPaint saveLayerPaint; saveLayerPaint.setAlpha(properties.getAlpha()); onBeginLayerOp(*new (mAllocator) BeginLayerOp( deferBeginLayerOp(*new (mAllocator) BeginLayerOp( saveLayerBounds, Matrix4::identity(), saveLayerBounds, &saveLayerPaint)); deferNodeOps(node); onEndLayerOp(*new (mAllocator) EndLayerOp()); deferEndLayerOp(*new (mAllocator) EndLayerOp()); } else { deferNodeOps(node); } Loading Loading @@ -559,7 +559,7 @@ void OpReorderer::defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedN } const RenderNodeOp* childOp = zTranslatedNodes[drawIndex].value; deferRenderNodeOp(*childOp); deferRenderNodeOpImpl(*childOp); drawIndex++; } } Loading Loading @@ -645,7 +645,7 @@ void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) { int restoreTo = mCanvasState.save(SkCanvas::kMatrix_SaveFlag); mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor); deferRenderNodeOp(*childOp); deferRenderNodeOpImpl(*childOp); mCanvasState.restoreToCount(restoreTo); } Loading @@ -653,13 +653,13 @@ void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) { } /** * Used to define a list of lambdas referencing private OpReorderer::onXXXXOp() methods. * Used to define a list of lambdas referencing private OpReorderer::onXX::defer() methods. * * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas. * E.g. a BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&) */ #define OP_RECEIVER(Type) \ [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.on##Type(static_cast<const Type&>(op)); }, [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.defer##Type(static_cast<const Type&>(op)); }, void OpReorderer::deferNodeOps(const RenderNode& renderNode) { typedef void (*OpDispatcher) (OpReorderer& reorderer, const RecordedOp& op); static OpDispatcher receivers[] = { Loading Loading @@ -687,7 +687,7 @@ void OpReorderer::deferNodeOps(const RenderNode& renderNode) { } } void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) { void OpReorderer::deferRenderNodeOpImpl(const RenderNodeOp& op) { if (op.renderNode->nothingToDraw()) return; int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); Loading @@ -702,9 +702,9 @@ void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) { mCanvasState.restoreToCount(count); } void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) { void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) { if (!op.skipInOrderDraw) { deferRenderNodeOp(op); deferRenderNodeOpImpl(op); } } Loading @@ -712,7 +712,7 @@ void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) { * Defers an unmergeable, strokeable op, accounting correctly * for paint's style on the bounds being computed. */ void OpReorderer::onStrokeableOp(const RecordedOp& op, batchid_t batchId, void OpReorderer::deferStrokeableOp(const RecordedOp& op, batchid_t batchId, BakedOpState::StrokeBehavior strokeBehavior) { // Note: here we account for stroke when baking the op BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct( Loading @@ -734,11 +734,11 @@ static batchid_t tessBatchId(const RecordedOp& op) { : (paint.isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices); } void OpReorderer::onArcOp(const ArcOp& op) { onStrokeableOp(op, tessBatchId(op)); void OpReorderer::deferArcOp(const ArcOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void OpReorderer::onBitmapOp(const BitmapOp& op) { void OpReorderer::deferBitmapOp(const BitmapOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -757,28 +757,43 @@ void OpReorderer::onBitmapOp(const BitmapOp& op) { } } void OpReorderer::onBitmapMeshOp(const BitmapMeshOp& op) { void OpReorderer::deferBitmapMeshOp(const BitmapMeshOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap); } void OpReorderer::onBitmapRectOp(const BitmapRectOp& op) { void OpReorderer::deferBitmapRectOp(const BitmapRectOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap); } void OpReorderer::onLinesOp(const LinesOp& op) { void OpReorderer::deferCirclePropsOp(const CirclePropsOp& op) { // allocate a temporary oval op (with mAllocator, so it persists until render), so the // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple. float x = *(op.x); float y = *(op.y); float radius = *(op.radius); Rect unmappedBounds(x - radius, y - radius, x + radius, y + radius); const OvalOp* resolvedOp = new (mAllocator) OvalOp( unmappedBounds, op.localMatrix, op.localClipRect, op.paint); deferOvalOp(*resolvedOp); } void OpReorderer::deferLinesOp(const LinesOp& op) { batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices; onStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); } void OpReorderer::onOvalOp(const OvalOp& op) { onStrokeableOp(op, tessBatchId(op)); void OpReorderer::deferOvalOp(const OvalOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void OpReorderer::onPatchOp(const PatchOp& op) { void OpReorderer::deferPatchOp(const PatchOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading @@ -795,30 +810,41 @@ void OpReorderer::onPatchOp(const PatchOp& op) { } } void OpReorderer::onPathOp(const PathOp& op) { onStrokeableOp(op, OpBatchType::Bitmap); void OpReorderer::deferPathOp(const PathOp& op) { deferStrokeableOp(op, OpBatchType::Bitmap); } void OpReorderer::onPointsOp(const PointsOp& op) { void OpReorderer::deferPointsOp(const PointsOp& op) { batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices; onStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced); } void OpReorderer::deferRectOp(const RectOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void OpReorderer::onRectOp(const RectOp& op) { onStrokeableOp(op, tessBatchId(op)); void OpReorderer::deferRoundRectOp(const RoundRectOp& op) { deferStrokeableOp(op, tessBatchId(op)); } void OpReorderer::onRoundRectOp(const RoundRectOp& op) { onStrokeableOp(op, tessBatchId(op)); void OpReorderer::deferRoundRectPropsOp(const RoundRectPropsOp& op) { // allocate a temporary round rect op (with mAllocator, so it persists until render), so the // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple. const RoundRectOp* resolvedOp = new (mAllocator) RoundRectOp( Rect(*(op.left), *(op.top), *(op.right), *(op.bottom)), op.localMatrix, op.localClipRect, op.paint, *op.rx, *op.ry); deferRoundRectOp(*resolvedOp); } void OpReorderer::onSimpleRectsOp(const SimpleRectsOp& op) { void OpReorderer::deferSimpleRectsOp(const SimpleRectsOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices); } void OpReorderer::onTextOp(const TextOp& op) { void OpReorderer::deferTextOp(const TextOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected Loading Loading @@ -861,7 +887,7 @@ void OpReorderer::restoreForLayer() { } // TODO: test rejection at defer time, where the bounds become empty void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) { void OpReorderer::deferBeginLayerOp(const BeginLayerOp& op) { uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth(); uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight(); Loading Loading @@ -906,7 +932,7 @@ void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) { &op, nullptr); } void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) { void OpReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) { const BeginLayerOp& beginLayerOp = *currentLayer().beginLayerOp; int finishedLayerIndex = mLayerStack.back(); Loading @@ -932,11 +958,11 @@ void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) { } } void OpReorderer::onLayerOp(const LayerOp& op) { void OpReorderer::deferLayerOp(const LayerOp& op) { LOG_ALWAYS_FATAL("unsupported"); } void OpReorderer::onShadowOp(const ShadowOp& op) { void OpReorderer::deferShadowOp(const ShadowOp& op) { LOG_ALWAYS_FATAL("unsupported"); } Loading
libs/hwui/OpReorderer.h +4 −4 Original line number Diff line number Diff line Loading @@ -237,7 +237,7 @@ private: void deferNodeOps(const RenderNode& renderNode); void deferRenderNodeOp(const RenderNodeOp& op); void deferRenderNodeOpImpl(const RenderNodeOp& op); void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers); Loading @@ -246,17 +246,17 @@ private: return mFrameAllocatedPaths.back().get(); } void onStrokeableOp(const RecordedOp& op, batchid_t batchId, void deferStrokeableOp(const RecordedOp& op, batchid_t batchId, BakedOpState::StrokeBehavior strokeBehavior = BakedOpState::StrokeBehavior::StyleDefined); /** * Declares all OpReorderer::onXXXXOp() methods for every RecordedOp type. * Declares all OpReorderer::deferXXXXOp() methods for every RecordedOp type. * * These private methods are called from within deferImpl to defer each individual op * type differently. */ #define INTERNAL_OP_HANDLER(Type) \ void on##Type(const Type& op); void defer##Type(const Type& op); MAP_OPS(INTERNAL_OP_HANDLER) std::vector<std::unique_ptr<SkPath> > mFrameAllocatedPaths; Loading
libs/hwui/RecordedOp.h +32 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ struct Vertex; M_OP_FN(BitmapOp) \ U_OP_FN(BitmapMeshOp) \ U_OP_FN(BitmapRectOp) \ U_OP_FN(CirclePropsOp) \ U_OP_FN(LinesOp) \ U_OP_FN(OvalOp) \ M_OP_FN(PatchOp) \ Loading @@ -56,6 +57,7 @@ struct Vertex; U_OP_FN(RectOp) \ U_OP_FN(RenderNodeOp) \ U_OP_FN(RoundRectOp) \ U_OP_FN(RoundRectPropsOp) \ U_OP_FN(ShadowOp) \ U_OP_FN(SimpleRectsOp) \ M_OP_FN(TextOp) \ Loading Loading @@ -181,6 +183,18 @@ struct BitmapRectOp : RecordedOp { const Rect src; }; struct CirclePropsOp : RecordedOp { CirclePropsOp(const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint, float* x, float* y, float* radius) : RecordedOp(RecordedOpId::CirclePropsOp, Rect(), localMatrix, localClipRect, paint) , x(x) , y(y) , radius(radius) {} const float* x; const float* y; const float* radius; }; struct LinesOp : RecordedOp { LinesOp(BASE_PARAMS, const float* points, const int floatCount) : SUPER(LinesOp) Loading @@ -195,7 +209,6 @@ struct OvalOp : RecordedOp { : SUPER(OvalOp) {} }; struct PatchOp : RecordedOp { PatchOp(BASE_PARAMS, const SkBitmap* bitmap, const Res_png_9patch* patch) : SUPER(PatchOp) Loading Loading @@ -235,6 +248,24 @@ struct RoundRectOp : RecordedOp { const float ry; }; struct RoundRectPropsOp : RecordedOp { RoundRectPropsOp(const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint, float* left, float* top, float* right, float* bottom, float *rx, float *ry) : RecordedOp(RecordedOpId::RoundRectPropsOp, Rect(), localMatrix, localClipRect, paint) , left(left) , top(top) , right(right) , bottom(bottom) , rx(rx) , ry(ry) {} const float* left; const float* top; const float* right; const float* bottom; const float* rx; const float* ry; }; /** * Real-time, dynamic-lit shadow. * Loading
libs/hwui/RecordingCanvas.cpp +38 −0 Original line number Diff line number Diff line Loading @@ -343,11 +343,49 @@ void RecordingCanvas::drawRoundRect(float left, float top, float right, float bo refPaint(&paint), rx, ry)); } 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(new (alloc()) RoundRectPropsOp( *(mState.currentSnapshot()->transform), mState.getRenderTargetClipBounds(), &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 (radius <= 0) 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(new (alloc()) CirclePropsOp( *(mState.currentSnapshot()->transform), mState.getRenderTargetClipBounds(), &paint->value, &x->value, &y->value, &radius->value)); } void RecordingCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) { addOp(new (alloc()) OvalOp( Rect(left, top, right, bottom), Loading