diff options
Diffstat (limited to 'libs/hwui/SkiaCanvasProxy.cpp')
-rw-r--r-- | libs/hwui/SkiaCanvasProxy.cpp | 199 |
1 files changed, 98 insertions, 101 deletions
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp index 16a19ca4d36a..fc009d871620 100644 --- a/libs/hwui/SkiaCanvasProxy.cpp +++ b/libs/hwui/SkiaCanvasProxy.cpp @@ -20,18 +20,18 @@ #include <log/log.h> -#include "hwui/Bitmap.h" #include <SkLatticeIter.h> -#include <SkPatchUtils.h> #include <SkPaint.h> +#include <SkPatchUtils.h> #include <SkPath.h> #include <SkPixelRef.h> -#include <SkRect.h> #include <SkRRect.h> #include <SkRSXform.h> +#include <SkRect.h> #include <SkSurface.h> #include <SkTextBlobRunIterator.h> #include <SkVertices.h> +#include "hwui/Bitmap.h" namespace android { namespace uirenderer { @@ -46,13 +46,13 @@ void SkiaCanvasProxy::onDrawPaint(const SkPaint& paint) { } void SkiaCanvasProxy::onDrawPoints(PointMode pointMode, size_t count, const SkPoint pts[], - const SkPaint& paint) { + const SkPaint& paint) { if (!pts || count == 0) { return; } // convert the SkPoints into floats - static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats"); + static_assert(sizeof(SkPoint) == sizeof(float) * 2, "SkPoint is no longer two floats"); const size_t floatCount = count << 1; const float* floatArray = &pts[0].fX; @@ -72,7 +72,7 @@ void SkiaCanvasProxy::onDrawPoints(PointMode pointMode, size_t count, const SkPo SkPath path; for (size_t i = 0; i < count - 1; i++) { path.moveTo(pts[i]); - path.lineTo(pts[i+1]); + path.lineTo(pts[i + 1]); this->drawPath(path, strokedPaint); path.rewind(); } @@ -95,8 +95,8 @@ void SkiaCanvasProxy::onDrawRRect(const SkRRect& roundRect, const SkPaint& paint if (!roundRect.isComplex()) { const SkRect& rect = roundRect.rect(); SkVector radii = roundRect.getSimpleRadii(); - mCanvas->drawRoundRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, - radii.fX, radii.fY, paint); + mCanvas->drawRoundRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, radii.fX, radii.fY, + paint); } else { SkPath path; path.addRRect(roundRect); @@ -106,8 +106,8 @@ void SkiaCanvasProxy::onDrawRRect(const SkRRect& roundRect, const SkPaint& paint void SkiaCanvasProxy::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const SkPaint& paint) { - mCanvas->drawArc(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, - startAngle, sweepAngle, useCenter, paint); + mCanvas->drawArc(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, startAngle, sweepAngle, + useCenter, paint); } void SkiaCanvasProxy::onDrawPath(const SkPath& path, const SkPaint& paint) { @@ -115,41 +115,38 @@ void SkiaCanvasProxy::onDrawPath(const SkPath& path, const SkPaint& paint) { } void SkiaCanvasProxy::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, - const SkPaint* paint) { + const SkPaint* paint) { sk_sp<Bitmap> hwuiBitmap = Bitmap::createFrom(bitmap.info(), *bitmap.pixelRef()); // HWUI doesn't support extractSubset(), so convert any subsetted bitmap into // a drawBitmapRect(); pass through an un-subsetted bitmap. if (hwuiBitmap && bitmap.dimensions() != hwuiBitmap->info().dimensions()) { SkIPoint origin = bitmap.pixelRefOrigin(); - mCanvas->drawBitmap(*hwuiBitmap, origin.fX, origin.fY, - origin.fX + bitmap.dimensions().width(), - origin.fY + bitmap.dimensions().height(), - left, top, - left + bitmap.dimensions().width(), - top + bitmap.dimensions().height(), - paint); + mCanvas->drawBitmap( + *hwuiBitmap, origin.fX, origin.fY, origin.fX + bitmap.dimensions().width(), + origin.fY + bitmap.dimensions().height(), left, top, + left + bitmap.dimensions().width(), top + bitmap.dimensions().height(), paint); } else { mCanvas->drawBitmap(*hwuiBitmap, left, top, paint); } } void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& skBitmap, const SkRect* srcPtr, - const SkRect& dst, const SkPaint* paint, SrcRectConstraint) { + const SkRect& dst, const SkPaint* paint, SrcRectConstraint) { SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(skBitmap.width(), skBitmap.height()); // TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src? - Bitmap* bitmap = reinterpret_cast<Bitmap*>(skBitmap.pixelRef()); - mCanvas->drawBitmap(*bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, - dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint); + Bitmap* bitmap = reinterpret_cast<Bitmap*>(skBitmap.pixelRef()); + mCanvas->drawBitmap(*bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, dst.fLeft, dst.fTop, + dst.fRight, dst.fBottom, paint); } void SkiaCanvasProxy::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, - const SkRect& dst, const SkPaint*) { - //TODO make nine-patch drawing a method on Canvas.h + const SkRect& dst, const SkPaint*) { + // TODO make nine-patch drawing a method on Canvas.h SkDEBUGFAIL("SkiaCanvasProxy::onDrawBitmapNine is not yet supported"); } void SkiaCanvasProxy::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, - const SkPaint* paint) { + const SkPaint* paint) { SkBitmap skiaBitmap; SkPixmap pixmap; if (image->peekPixels(&pixmap) && skiaBitmap.installPixels(pixmap)) { @@ -158,33 +155,33 @@ void SkiaCanvasProxy::onDrawImage(const SkImage* image, SkScalar left, SkScalar } void SkiaCanvasProxy::onDrawImageRect(const SkImage* image, const SkRect* srcPtr, const SkRect& dst, - const SkPaint* paint, SrcRectConstraint constraint) { + const SkPaint* paint, SrcRectConstraint constraint) { SkBitmap skiaBitmap; SkPixmap pixmap; if (image->peekPixels(&pixmap) && skiaBitmap.installPixels(pixmap)) { sk_sp<Bitmap> bitmap = Bitmap::createFrom(skiaBitmap.info(), *skiaBitmap.pixelRef()); SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(image->width(), image->height()); - mCanvas->drawBitmap(*bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, - dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint); + mCanvas->drawBitmap(*bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, dst.fLeft, + dst.fTop, dst.fRight, dst.fBottom, paint); } } void SkiaCanvasProxy::onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, - const SkPaint*) { + const SkPaint*) { SkDEBUGFAIL("SkiaCanvasProxy::onDrawImageNine is not yet supported"); } void SkiaCanvasProxy::onDrawImageLattice(const SkImage* image, const Lattice& lattice, - const SkRect& dst, const SkPaint* paint) { + const SkRect& dst, const SkPaint* paint) { SkLatticeIter iter(lattice, dst); SkRect srcR, dstR; while (iter.next(&srcR, &dstR)) { - onDrawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint); + onDrawImageRect(image, &srcR, dstR, paint, SkCanvas::kFast_SrcRectConstraint); } } void SkiaCanvasProxy::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode, - const SkPaint& paint) { + const SkPaint& paint) { if (mFilterHwuiCalls) { return; } @@ -207,14 +204,11 @@ static inline SaveFlags::Flags saveFlags(SkCanvas::SaveLayerFlags layerFlags) { saveFlags |= SaveFlags::ClipToLayer; } - if (!(layerFlags & SkCanvas::kIsOpaque_SaveLayerFlag)) { - saveFlags |= SaveFlags::HasAlphaLayer; - } - return saveFlags; } -SkCanvas::SaveLayerStrategy SkiaCanvasProxy::getSaveLayerStrategy(const SaveLayerRec& saveLayerRec) { +SkCanvas::SaveLayerStrategy SkiaCanvasProxy::getSaveLayerStrategy( + const SaveLayerRec& saveLayerRec) { SkRect rect; if (saveLayerRec.fBounds) { rect = *saveLayerRec.fBounds; @@ -239,7 +233,7 @@ void SkiaCanvasProxy::didSetMatrix(const SkMatrix& matrix) { } void SkiaCanvasProxy::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, - const SkPaint& paint) { + const SkPaint& paint) { SkPath path; path.addRRect(outer); path.addRRect(inner); @@ -259,7 +253,7 @@ public: glyphIDs = (uint16_t*)text; count = byteLength >> 1; } else { - // ensure space for one glyph per ID given UTF8 encoding. + // ensure space for one glyph per ID given UTF8 encoding. storage.reset(new uint16_t[byteLength]); glyphIDs = storage.get(); count = paint.textToGlyphs(text, byteLength, storage.get()); @@ -270,12 +264,13 @@ public: SkPaint paint; uint16_t* glyphIDs; int count; + private: std::unique_ptr<uint16_t[]> storage; }; void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, - const SkPaint& origPaint) { + const SkPaint& origPaint) { // convert to glyphIDs if necessary GlyphIDConverter glyphs(text, byteLength, origPaint); @@ -309,14 +304,14 @@ void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x int xBaseline = 0; int yBaseline = 0; if (mCanvas->drawTextAbsolutePos()) { - bounds.offset(x,y); + bounds.offset(x, y); xBaseline = x; yBaseline = y; } - static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats"); - auto glyphFunc = [&] (uint16_t* text, float* positions) { - memcpy(text, glyphs.glyphIDs, glyphs.count*sizeof(uint16_t)); + static_assert(sizeof(SkPoint) == sizeof(float) * 2, "SkPoint is no longer two floats"); + auto glyphFunc = [&](uint16_t* text, float* positions) { + memcpy(text, glyphs.glyphIDs, glyphs.count * sizeof(uint16_t)); size_t posIndex = 0; // setup the first glyph position positions[posIndex++] = xBaseline; @@ -326,24 +321,24 @@ void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x float yPosition = yBaseline; for (int i = 1; i < glyphs.count; i++) { positions[posIndex++] = xBaseline; - yPosition += glyphWidths[i-1]; + yPosition += glyphWidths[i - 1]; positions[posIndex++] = yPosition; } } else { float xPosition = xBaseline; for (int i = 1; i < glyphs.count; i++) { - xPosition += glyphWidths[i-1]; + xPosition += glyphWidths[i - 1]; positions[posIndex++] = xPosition; positions[posIndex++] = yBaseline; } } }; mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop, - bounds.fRight, bounds.fBottom, 0); + bounds.fRight, bounds.fBottom, 0); } void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], - const SkPaint& origPaint) { + const SkPaint& origPaint) { // convert to glyphIDs if necessary GlyphIDConverter glyphs(text, byteLength, origPaint); @@ -369,11 +364,11 @@ void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const S bounds.join(glyphBounds); } - static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats"); - auto glyphFunc = [&] (uint16_t* text, float* positions) { - memcpy(text, glyphs.glyphIDs, glyphs.count*sizeof(uint16_t)); + static_assert(sizeof(SkPoint) == sizeof(float) * 2, "SkPoint is no longer two floats"); + auto glyphFunc = [&](uint16_t* text, float* positions) { + memcpy(text, glyphs.glyphIDs, glyphs.count * sizeof(uint16_t)); if (mCanvas->drawTextAbsolutePos()) { - memcpy(positions, pos, 2*glyphs.count*sizeof(float)); + memcpy(positions, pos, 2 * glyphs.count * sizeof(float)); } else { for (int i = 0, posIndex = 0; i < glyphs.count; i++) { positions[posIndex++] = pos[i].fX - x; @@ -382,11 +377,11 @@ void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const S } }; mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop, - bounds.fRight, bounds.fBottom, 0); + bounds.fRight, bounds.fBottom, 0); } void SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], - SkScalar constY, const SkPaint& paint) { + SkScalar constY, const SkPaint& paint) { const size_t pointCount = byteLength >> 1; std::unique_ptr<SkPoint[]> pts(new SkPoint[pointCount]); for (size_t i = 0; i < pointCount; i++) { @@ -396,13 +391,14 @@ void SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const } void SkiaCanvasProxy::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, - const SkMatrix* matrix, const SkPaint& origPaint) { + const SkMatrix* matrix, const SkPaint& origPaint) { SkDEBUGFAIL("SkiaCanvasProxy::onDrawTextOnPath is not supported"); } void SkiaCanvasProxy::onDrawTextRSXform(const void* text, size_t byteLength, - const SkRSXform xform[], const SkRect* cullRect, const SkPaint& paint) { - GlyphIDConverter glyphs(text, byteLength, paint); // Just get count + const SkRSXform xform[], const SkRect* cullRect, + const SkPaint& paint) { + GlyphIDConverter glyphs(text, byteLength, paint); // Just get count SkMatrix localM, currM, origM; mCanvas->getMatrix(&currM); origM = currM; @@ -410,55 +406,56 @@ void SkiaCanvasProxy::onDrawTextRSXform(const void* text, size_t byteLength, localM.setRSXform(*xform++); currM.setConcat(origM, localM); mCanvas->setMatrix(currM); - this->onDrawText((char*)text + (byteLength / glyphs.count * i), - byteLength / glyphs.count, 0, 0, paint); + this->onDrawText((char*)text + (byteLength / glyphs.count * i), byteLength / glyphs.count, + 0, 0, paint); } mCanvas->setMatrix(origM); } - void SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, - const SkPaint& paint) { + const SkPaint& paint) { SkPaint runPaint = paint; - SkTextBlobRunIterator it(blob); - for (;!it.done(); it.next()) { - size_t textLen = it.glyphCount() * sizeof(uint16_t); - const SkPoint& offset = it.offset(); - // applyFontToPaint() always overwrites the exact same attributes, - // so it is safe to not re-seed the paint for this reason. - it.applyFontToPaint(&runPaint); - - switch (it.positioning()) { - case SkTextBlob::kDefault_Positioning: - this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint); - break; - case SkTextBlob::kHorizontal_Positioning: { - std::unique_ptr<SkPoint[]> pts(new SkPoint[it.glyphCount()]); - for (size_t i = 0; i < it.glyphCount(); i++) { - pts[i].set(x + offset.x() + it.pos()[i], y + offset.y()); - } - this->drawPosText(it.glyphs(), textLen, pts.get(), runPaint); - break; - } - case SkTextBlob::kFull_Positioning: { - std::unique_ptr<SkPoint[]> pts(new SkPoint[it.glyphCount()]); - for (size_t i = 0; i < it.glyphCount(); i++) { - const size_t xIndex = i*2; - const size_t yIndex = xIndex + 1; - pts[i].set(x + offset.x() + it.pos()[xIndex], y + offset.y() + it.pos()[yIndex]); - } - this->drawPosText(it.glyphs(), textLen, pts.get(), runPaint); - break; - } - default: - SkFAIL("unhandled positioning mode"); - } - } + SkTextBlobRunIterator it(blob); + for (; !it.done(); it.next()) { + size_t textLen = it.glyphCount() * sizeof(uint16_t); + const SkPoint& offset = it.offset(); + // applyFontToPaint() always overwrites the exact same attributes, + // so it is safe to not re-seed the paint for this reason. + it.applyFontToPaint(&runPaint); + + switch (it.positioning()) { + case SkTextBlob::kDefault_Positioning: + this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint); + break; + case SkTextBlob::kHorizontal_Positioning: { + std::unique_ptr<SkPoint[]> pts(new SkPoint[it.glyphCount()]); + for (size_t i = 0; i < it.glyphCount(); i++) { + pts[i].set(x + offset.x() + it.pos()[i], y + offset.y()); + } + this->drawPosText(it.glyphs(), textLen, pts.get(), runPaint); + break; + } + case SkTextBlob::kFull_Positioning: { + std::unique_ptr<SkPoint[]> pts(new SkPoint[it.glyphCount()]); + for (size_t i = 0; i < it.glyphCount(); i++) { + const size_t xIndex = i * 2; + const size_t yIndex = xIndex + 1; + pts[i].set(x + offset.x() + it.pos()[xIndex], + y + offset.y() + it.pos()[yIndex]); + } + this->drawPosText(it.glyphs(), textLen, pts.get(), runPaint); + break; + } + default: + SK_ABORT("unhandled positioning mode"); + } + } } void SkiaCanvasProxy::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], - const SkPoint texCoords[4], SkBlendMode bmode, const SkPaint& paint) { + const SkPoint texCoords[4], SkBlendMode bmode, + const SkPaint& paint) { if (mFilterHwuiCalls) { return; } @@ -466,9 +463,9 @@ void SkiaCanvasProxy::onDrawPatch(const SkPoint cubics[12], const SkColor colors mCanvas->getMatrix(&matrix); SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix); - mCanvas->drawVertices(SkPatchUtils::MakeVertices(cubics, colors, texCoords, - lod.width(), lod.height()).get(), - bmode, paint); + mCanvas->drawVertices( + SkPatchUtils::MakeVertices(cubics, colors, texCoords, lod.width(), lod.height()).get(), + bmode, paint); } void SkiaCanvasProxy::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle) { @@ -485,5 +482,5 @@ void SkiaCanvasProxy::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle) mCanvas->clipPath(&path, op); } -}; // namespace uirenderer -}; // namespace android +}; // namespace uirenderer +}; // namespace android |