summaryrefslogtreecommitdiff
path: root/libs/hwui/SkiaCanvasProxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/SkiaCanvasProxy.cpp')
-rw-r--r--libs/hwui/SkiaCanvasProxy.cpp199
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