Loading libs/hwui/RecordingCanvas.cpp +11 −11 Original line number Diff line number Diff line Loading @@ -268,7 +268,7 @@ static Rect calcBoundsOfPoints(const float* points, int floatCount) { // Geometry void RecordingCanvas::drawPoints(const float* points, int floatCount, const SkPaint& paint) { if (CC_UNLIKELY(floatCount < 2 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(floatCount < 2 || paint.nothingToDraw())) return; floatCount &= ~0x1; // round down to nearest two addOp(alloc().create_trivial<PointsOp>( Loading @@ -279,7 +279,7 @@ void RecordingCanvas::drawPoints(const float* points, int floatCount, const SkPa } void RecordingCanvas::drawLines(const float* points, int floatCount, const SkPaint& paint) { if (CC_UNLIKELY(floatCount < 4 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(floatCount < 4 || paint.nothingToDraw())) return; floatCount &= ~0x3; // round down to nearest four addOp(alloc().create_trivial<LinesOp>( Loading @@ -290,7 +290,7 @@ void RecordingCanvas::drawLines(const float* points, int floatCount, const SkPai } void RecordingCanvas::drawRect(float left, float top, float right, float bottom, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; addOp(alloc().create_trivial<RectOp>( Rect(left, top, right, bottom), Loading Loading @@ -333,7 +333,7 @@ void RecordingCanvas::drawSimpleRects(const float* rects, int vertexCount, const } void RecordingCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; if (paint.getStyle() == SkPaint::kFill_Style && (!paint.isAntiAlias() || mState.currentTransform()->isSimple())) { Loading Loading @@ -362,7 +362,7 @@ void RecordingCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { void RecordingCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; if (CC_LIKELY(MathUtils::isPositive(rx) || MathUtils::isPositive(ry))) { addOp(alloc().create_trivial<RoundRectOp>( Loading Loading @@ -398,7 +398,7 @@ void RecordingCanvas::drawRoundRect( void RecordingCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { // TODO: move to Canvas.h if (CC_UNLIKELY(radius <= 0 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return; drawOval(x - radius, y - radius, x + radius, y + radius, paint); } Loading @@ -419,7 +419,7 @@ void RecordingCanvas::drawCircle( } void RecordingCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; addOp(alloc().create_trivial<OvalOp>( Rect(left, top, right, bottom), Loading @@ -430,7 +430,7 @@ void RecordingCanvas::drawOval(float left, float top, float right, float bottom, void RecordingCanvas::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; if (fabs(sweepAngle) >= 360.0f) { drawOval(left, top, right, bottom, paint); Loading @@ -445,7 +445,7 @@ void RecordingCanvas::drawArc(float left, float top, float right, float bottom, } void RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; addOp(alloc().create_trivial<PathOp>( Rect(path.getBounds()), Loading Loading @@ -543,7 +543,7 @@ void RecordingCanvas::drawNinePatch(Bitmap& bitmap, const android::Res_png_9patc void RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) { if (!glyphs || !positions || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; if (!glyphs || !positions || glyphCount <= 0 || paint.nothingToDraw()) return; glyphs = refBuffer<glyph_t>(glyphs, glyphCount); positions = refBuffer<float>(positions, glyphCount * 2); Loading @@ -563,7 +563,7 @@ void RecordingCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOff glyphs[0] = layout.getGlyphId(i); float x = hOffset + layout.getX(i); float y = vOffset + layout.getY(i); if (PaintUtils::paintWillNotDrawText(paint)) return; if (paint.nothingToDraw()) return; const uint16_t* tempGlyphs = refBuffer<glyph_t>(glyphs, 1); addOp(alloc().create_trivial<TextOnPathOp>( *(mState.currentSnapshot()->transform), Loading libs/hwui/SkiaCanvas.cpp +10 −10 Original line number Diff line number Diff line Loading @@ -443,7 +443,7 @@ void SkiaCanvas::drawPaint(const SkPaint& paint) { void SkiaCanvas::drawPoints(const float* points, int count, const SkPaint& paint, SkCanvas::PointMode mode) { if (CC_UNLIKELY(count < 2 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(count < 2 || paint.nothingToDraw())) return; // convert the floats into SkPoints count >>= 1; // now it is the number of points std::unique_ptr<SkPoint[]> pts(new SkPoint[count]); Loading @@ -469,49 +469,49 @@ void SkiaCanvas::drawLine(float startX, float startY, float stopX, float stopY, } void SkiaCanvas::drawLines(const float* points, int count, const SkPaint& paint) { if (CC_UNLIKELY(count < 4 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(count < 4 || paint.nothingToDraw())) return; this->drawPoints(points, count, paint, SkCanvas::kLines_PointMode); } void SkiaCanvas::drawRect(float left, float top, float right, float bottom, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; mCanvas->drawRectCoords(left, top, right, bottom, paint); } void SkiaCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; mCanvas->drawRegion(region, paint); } void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); mCanvas->drawRoundRect(rect, rx, ry, paint); } void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { if (CC_UNLIKELY(radius <= 0 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return; mCanvas->drawCircle(x, y, radius, paint); } void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect oval = SkRect::MakeLTRB(left, top, right, bottom); mCanvas->drawOval(oval, paint); } void SkiaCanvas::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect arc = SkRect::MakeLTRB(left, top, right, bottom); mCanvas->drawArc(arc, startAngle, sweepAngle, useCenter, paint); } void SkiaCanvas::drawPath(const SkPath& path, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect rect; SkRRect roundRect; if (path.isOval(&rect)) { Loading Loading @@ -698,7 +698,7 @@ void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int co const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) { if (!text || !positions || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; if (!text || !positions || count <= 0 || paint.nothingToDraw()) return; // Set align to left for drawing, as we don't want individual // glyphs centered or right-aligned; the offset above takes // care of all alignment. Loading libs/hwui/tests/unit/SkiaCanvasTests.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <gtest/gtest.h> #include <RecordingCanvas.h> #include <SkBlurDrawLooper.h> #include <SkPicture.h> #include <SkPictureRecorder.h> Loading Loading @@ -59,3 +60,21 @@ OPENGL_PIPELINE_TEST(SkiaCanvasProxy, drawGlyphsViaPicture) { EXPECT_EQ(directOp->unmappedBounds, pictureOp->unmappedBounds); EXPECT_EQ(directOp->localMatrix, pictureOp->localMatrix); } TEST(SkiaCanvas, drawShadowLayer) { auto surface = SkSurface::MakeRasterN32Premul(10, 10); SkiaCanvas canvas(surface->getCanvas()); // clear to white canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrc); SkPaint paint; // it is transparent to ensure that we still draw the rect since it has a looper paint.setColor(SK_ColorTRANSPARENT); // this is how view's shadow layers are implemented paint.setLooper(SkBlurDrawLooper::Make(0xF0000000, 6.0f, 0, 10)); canvas.drawRect(3, 3, 7, 7, paint); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE); ASSERT_NE(TestUtils::getColor(surface, 5, 5), SK_ColorWHITE); } libs/hwui/utils/PaintUtils.h +0 −15 Original line number Diff line number Diff line Loading @@ -39,21 +39,6 @@ public: return GL_NEAREST; } // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()? static inline bool paintWillNotDraw(const SkPaint& paint) { return paint.getAlpha() == 0 && !paint.getColorFilter() && paint.getBlendMode() == SkBlendMode::kSrcOver; } // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()? static inline bool paintWillNotDrawText(const SkPaint& paint) { return paint.getAlpha() == 0 && paint.getLooper() == nullptr && !paint.getColorFilter() && paint.getBlendMode() == SkBlendMode::kSrcOver; } static bool isOpaquePaint(const SkPaint* paint) { if (!paint) return true; // default (paintless) behavior is SrcOver, black Loading Loading
libs/hwui/RecordingCanvas.cpp +11 −11 Original line number Diff line number Diff line Loading @@ -268,7 +268,7 @@ static Rect calcBoundsOfPoints(const float* points, int floatCount) { // Geometry void RecordingCanvas::drawPoints(const float* points, int floatCount, const SkPaint& paint) { if (CC_UNLIKELY(floatCount < 2 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(floatCount < 2 || paint.nothingToDraw())) return; floatCount &= ~0x1; // round down to nearest two addOp(alloc().create_trivial<PointsOp>( Loading @@ -279,7 +279,7 @@ void RecordingCanvas::drawPoints(const float* points, int floatCount, const SkPa } void RecordingCanvas::drawLines(const float* points, int floatCount, const SkPaint& paint) { if (CC_UNLIKELY(floatCount < 4 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(floatCount < 4 || paint.nothingToDraw())) return; floatCount &= ~0x3; // round down to nearest four addOp(alloc().create_trivial<LinesOp>( Loading @@ -290,7 +290,7 @@ void RecordingCanvas::drawLines(const float* points, int floatCount, const SkPai } void RecordingCanvas::drawRect(float left, float top, float right, float bottom, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; addOp(alloc().create_trivial<RectOp>( Rect(left, top, right, bottom), Loading Loading @@ -333,7 +333,7 @@ void RecordingCanvas::drawSimpleRects(const float* rects, int vertexCount, const } void RecordingCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; if (paint.getStyle() == SkPaint::kFill_Style && (!paint.isAntiAlias() || mState.currentTransform()->isSimple())) { Loading Loading @@ -362,7 +362,7 @@ void RecordingCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { void RecordingCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; if (CC_LIKELY(MathUtils::isPositive(rx) || MathUtils::isPositive(ry))) { addOp(alloc().create_trivial<RoundRectOp>( Loading Loading @@ -398,7 +398,7 @@ void RecordingCanvas::drawRoundRect( void RecordingCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { // TODO: move to Canvas.h if (CC_UNLIKELY(radius <= 0 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return; drawOval(x - radius, y - radius, x + radius, y + radius, paint); } Loading @@ -419,7 +419,7 @@ void RecordingCanvas::drawCircle( } void RecordingCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; addOp(alloc().create_trivial<OvalOp>( Rect(left, top, right, bottom), Loading @@ -430,7 +430,7 @@ void RecordingCanvas::drawOval(float left, float top, float right, float bottom, void RecordingCanvas::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; if (fabs(sweepAngle) >= 360.0f) { drawOval(left, top, right, bottom, paint); Loading @@ -445,7 +445,7 @@ void RecordingCanvas::drawArc(float left, float top, float right, float bottom, } void RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; addOp(alloc().create_trivial<PathOp>( Rect(path.getBounds()), Loading Loading @@ -543,7 +543,7 @@ void RecordingCanvas::drawNinePatch(Bitmap& bitmap, const android::Res_png_9patc void RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) { if (!glyphs || !positions || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; if (!glyphs || !positions || glyphCount <= 0 || paint.nothingToDraw()) return; glyphs = refBuffer<glyph_t>(glyphs, glyphCount); positions = refBuffer<float>(positions, glyphCount * 2); Loading @@ -563,7 +563,7 @@ void RecordingCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOff glyphs[0] = layout.getGlyphId(i); float x = hOffset + layout.getX(i); float y = vOffset + layout.getY(i); if (PaintUtils::paintWillNotDrawText(paint)) return; if (paint.nothingToDraw()) return; const uint16_t* tempGlyphs = refBuffer<glyph_t>(glyphs, 1); addOp(alloc().create_trivial<TextOnPathOp>( *(mState.currentSnapshot()->transform), Loading
libs/hwui/SkiaCanvas.cpp +10 −10 Original line number Diff line number Diff line Loading @@ -443,7 +443,7 @@ void SkiaCanvas::drawPaint(const SkPaint& paint) { void SkiaCanvas::drawPoints(const float* points, int count, const SkPaint& paint, SkCanvas::PointMode mode) { if (CC_UNLIKELY(count < 2 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(count < 2 || paint.nothingToDraw())) return; // convert the floats into SkPoints count >>= 1; // now it is the number of points std::unique_ptr<SkPoint[]> pts(new SkPoint[count]); Loading @@ -469,49 +469,49 @@ void SkiaCanvas::drawLine(float startX, float startY, float stopX, float stopY, } void SkiaCanvas::drawLines(const float* points, int count, const SkPaint& paint) { if (CC_UNLIKELY(count < 4 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(count < 4 || paint.nothingToDraw())) return; this->drawPoints(points, count, paint, SkCanvas::kLines_PointMode); } void SkiaCanvas::drawRect(float left, float top, float right, float bottom, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; mCanvas->drawRectCoords(left, top, right, bottom, paint); } void SkiaCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; mCanvas->drawRegion(region, paint); } void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); mCanvas->drawRoundRect(rect, rx, ry, paint); } void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { if (CC_UNLIKELY(radius <= 0 || PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return; mCanvas->drawCircle(x, y, radius, paint); } void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect oval = SkRect::MakeLTRB(left, top, right, bottom); mCanvas->drawOval(oval, paint); } void SkiaCanvas::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect arc = SkRect::MakeLTRB(left, top, right, bottom); mCanvas->drawArc(arc, startAngle, sweepAngle, useCenter, paint); } void SkiaCanvas::drawPath(const SkPath& path, const SkPaint& paint) { if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; if (CC_UNLIKELY(paint.nothingToDraw())) return; SkRect rect; SkRRect roundRect; if (path.isOval(&rect)) { Loading Loading @@ -698,7 +698,7 @@ void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int co const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, float totalAdvance) { if (!text || !positions || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; if (!text || !positions || count <= 0 || paint.nothingToDraw()) return; // Set align to left for drawing, as we don't want individual // glyphs centered or right-aligned; the offset above takes // care of all alignment. Loading
libs/hwui/tests/unit/SkiaCanvasTests.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <gtest/gtest.h> #include <RecordingCanvas.h> #include <SkBlurDrawLooper.h> #include <SkPicture.h> #include <SkPictureRecorder.h> Loading Loading @@ -59,3 +60,21 @@ OPENGL_PIPELINE_TEST(SkiaCanvasProxy, drawGlyphsViaPicture) { EXPECT_EQ(directOp->unmappedBounds, pictureOp->unmappedBounds); EXPECT_EQ(directOp->localMatrix, pictureOp->localMatrix); } TEST(SkiaCanvas, drawShadowLayer) { auto surface = SkSurface::MakeRasterN32Premul(10, 10); SkiaCanvas canvas(surface->getCanvas()); // clear to white canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrc); SkPaint paint; // it is transparent to ensure that we still draw the rect since it has a looper paint.setColor(SK_ColorTRANSPARENT); // this is how view's shadow layers are implemented paint.setLooper(SkBlurDrawLooper::Make(0xF0000000, 6.0f, 0, 10)); canvas.drawRect(3, 3, 7, 7, paint); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE); ASSERT_NE(TestUtils::getColor(surface, 5, 5), SK_ColorWHITE); }
libs/hwui/utils/PaintUtils.h +0 −15 Original line number Diff line number Diff line Loading @@ -39,21 +39,6 @@ public: return GL_NEAREST; } // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()? static inline bool paintWillNotDraw(const SkPaint& paint) { return paint.getAlpha() == 0 && !paint.getColorFilter() && paint.getBlendMode() == SkBlendMode::kSrcOver; } // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()? static inline bool paintWillNotDrawText(const SkPaint& paint) { return paint.getAlpha() == 0 && paint.getLooper() == nullptr && !paint.getColorFilter() && paint.getBlendMode() == SkBlendMode::kSrcOver; } static bool isOpaquePaint(const SkPaint* paint) { if (!paint) return true; // default (paintless) behavior is SrcOver, black Loading