summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Derek Sollenberger <djsollen@google.com> 2014-12-16 08:37:20 -0500
committer Derek Sollenberger <djsollen@google.com> 2015-01-30 12:56:37 -0500
commit1db141f93c4fe79a4669440c3d14f63bc87b2e34 (patch)
tree674930c62207ed50620d51b67448cffe3d01b43a
parent728dace14d83e87e777ceaaf3dfd031cf3502f80 (diff)
Create proxy between Skia's SkCanvas and the framework Canvas.
This enables Picture.java to be replayed into HWUI in addition to extending the Skia testing suite to HWUI. Bug: 19011232 Change-Id: Id27ac03eec817b0784763e62ab8413a07b3b8cb2
-rw-r--r--graphics/java/android/graphics/Picture.java5
-rw-r--r--libs/hwui/Android.common.mk1
-rw-r--r--libs/hwui/Canvas.h16
-rw-r--r--libs/hwui/DisplayListRenderer.cpp10
-rw-r--r--libs/hwui/DisplayListRenderer.h8
-rw-r--r--libs/hwui/SkiaCanvasProxy.cpp347
-rw-r--r--libs/hwui/SkiaCanvasProxy.h104
7 files changed, 474 insertions, 17 deletions
diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java
index fa9af2a4a450..39272b92fc11 100644
--- a/graphics/java/android/graphics/Picture.java
+++ b/graphics/java/android/graphics/Picture.java
@@ -122,11 +122,6 @@ public class Picture {
* @param canvas The picture is drawn to this canvas
*/
public void draw(Canvas canvas) {
- if (canvas.isHardwareAccelerated()) {
- throw new IllegalArgumentException(
- "Picture playback is only supported on software canvas.");
- }
-
if (mRecordingCanvas != null) {
endRecording();
}
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk
index 7c1a724835fe..c76b2b55f785 100644
--- a/libs/hwui/Android.common.mk
+++ b/libs/hwui/Android.common.mk
@@ -63,6 +63,7 @@ LOCAL_SRC_FILES := \
ResourceCache.cpp \
ShadowTessellator.cpp \
SkiaCanvas.cpp \
+ SkiaCanvasProxy.cpp \
SkiaShader.cpp \
Snapshot.cpp \
SpotShadow.cpp \
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index 45dc03a7a43f..7ad0683d9248 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -42,14 +42,14 @@ public:
*/
static Canvas* create_canvas(SkCanvas* skiaCanvas);
- // TODO: enable HWUI to either create similar canvas wrapper or subclass
- // directly from Canvas
- //static Canvas* create_canvas(uirenderer::Renderer* renderer);
-
- // TODO: this is a temporary affordance until all necessary logic can be
- // moved within this interface! Further, the return value should
- // NOT be unref'd and is valid until this canvas is destroyed or a
- // new bitmap is set.
+ /**
+ * Provides a Skia SkCanvas interface that acts as a proxy to this Canvas.
+ * It is useful for testing and clients (e.g. Picture/Movie) that expect to
+ * draw their contents into an SkCanvas.
+ *
+ * Further, the returned SkCanvas should NOT be unref'd and is valid until
+ * this canvas is destroyed or a new bitmap is set.
+ */
virtual SkCanvas* asSkCanvas() = 0;
virtual void setBitmap(SkBitmap* bitmap, bool copyState) = 0;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index d98d744d9e5a..23181bc2b61b 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -59,6 +59,7 @@ DisplayListData* DisplayListRenderer::finishRecording() {
mPathMap.clear();
DisplayListData* data = mDisplayListData;
mDisplayListData = nullptr;
+ mSkiaCanvasProxy.reset(nullptr);
return data;
}
@@ -94,6 +95,15 @@ void DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
mDisplayListData->functors.add(functor);
}
+SkCanvas* DisplayListRenderer::asSkCanvas() {
+ LOG_ALWAYS_FATAL_IF(!mDisplayListData,
+ "attempting to get an SkCanvas when we are not recording!");
+ if (!mSkiaCanvasProxy) {
+ mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this));
+ }
+ return mSkiaCanvasProxy.get();
+}
+
int DisplayListRenderer::save(SkCanvas::SaveFlags flags) {
addStateOp(new (alloc()) SaveOp((int) flags));
return mState.save((int) flags);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 527a0e5e23ff..bd0b3b7c6553 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -28,6 +28,7 @@
#include "Canvas.h"
#include "CanvasState.h"
#include "DisplayList.h"
+#include "SkiaCanvasProxy.h"
#include "RenderNode.h"
#include "Renderer.h"
#include "ResourceCache.h"
@@ -136,10 +137,8 @@ public:
// ----------------------------------------------------------------------------
// android/graphics/Canvas interface
// ----------------------------------------------------------------------------
- virtual SkCanvas* asSkCanvas() override {
- LOG_ALWAYS_FATAL("DisplayListRenderer has no SkCanvas");
- return nullptr;
- }
+ virtual SkCanvas* asSkCanvas() override;
+
virtual void setBitmap(SkBitmap* bitmap, bool copyState) override {
LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap.");
}
@@ -244,6 +243,7 @@ public:
private:
CanvasState mState;
+ std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy;
enum DeferredBarrierType {
kBarrier_None,
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
new file mode 100644
index 000000000000..de5f91c4ad8b
--- /dev/null
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -0,0 +1,347 @@
+/*
+ * 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 "SkiaCanvasProxy.h"
+
+#include <cutils/log.h>
+#include <SkPatchUtils.h>
+
+namespace android {
+namespace uirenderer {
+
+SkiaCanvasProxy::SkiaCanvasProxy(Canvas* canvas)
+ : INHERITED(canvas->width(), canvas->height())
+ , mCanvas(canvas) {}
+
+void SkiaCanvasProxy::onDrawPaint(const SkPaint& paint) {
+ mCanvas->drawPaint(paint);
+}
+
+void SkiaCanvasProxy::onDrawPoints(PointMode pointMode, size_t count, const SkPoint pts[],
+ const SkPaint& paint) {
+ // convert the SkPoints into floats
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ const size_t floatCount = count << 1;
+ const float* floatArray = &pts[0].fX;
+
+ switch (pointMode) {
+ case kPoints_PointMode: {
+ mCanvas->drawPoints(floatArray, floatCount, paint);
+ break;
+ }
+ case kLines_PointMode: {
+ mCanvas->drawLines(floatArray, floatCount, paint);
+ break;
+ }
+ case kPolygon_PointMode: {
+ SkPaint strokedPaint(paint);
+ strokedPaint.setStyle(SkPaint::kStroke_Style);
+
+ SkPath path;
+ for (size_t i = 0; i < count - 1; i++) {
+ path.moveTo(pts[i]);
+ path.lineTo(pts[i+1]);
+ this->drawPath(path, strokedPaint);
+ path.rewind();
+ }
+ break;
+ }
+ default:
+ LOG_ALWAYS_FATAL("Unknown point type");
+ }
+}
+
+void SkiaCanvasProxy::onDrawOval(const SkRect& rect, const SkPaint& paint) {
+ mCanvas->drawOval(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, paint);
+}
+
+void SkiaCanvasProxy::onDrawRect(const SkRect& rect, const SkPaint& paint) {
+ mCanvas->drawRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, paint);
+}
+
+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);
+ } else {
+ SkPath path;
+ path.addRRect(roundRect);
+ mCanvas->drawPath(path, paint);
+ }
+}
+
+void SkiaCanvasProxy::onDrawPath(const SkPath& path, const SkPaint& paint) {
+ mCanvas->drawPath(path, paint);
+}
+
+void SkiaCanvasProxy::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint) {
+ mCanvas->drawBitmap(bitmap, left, top, paint);
+}
+
+void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* srcPtr,
+ const SkRect& dst, const SkPaint* paint, DrawBitmapRectFlags) {
+ SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(bitmap.width(), bitmap.height());
+ 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
+ SkDEBUGFAIL("SkiaCanvasProxy::onDrawBitmapNine is not yet supported");
+}
+
+void SkiaCanvasProxy::onDrawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint) {
+ mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
+ mCanvas->setMatrix(SkMatrix::I());
+ mCanvas->drawBitmap(bitmap, left, top, paint);
+ mCanvas->restore();
+}
+
+void SkiaCanvasProxy::onDrawVertices(VertexMode mode, int vertexCount, const SkPoint vertices[],
+ const SkPoint texs[], const SkColor colors[], SkXfermode*, const uint16_t indices[],
+ int indexCount, const SkPaint& paint) {
+ // convert the SkPoints into floats
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ const int floatCount = vertexCount << 1;
+ const float* vArray = &vertices[0].fX;
+ const float* tArray = (texs) ? &texs[0].fX : NULL;
+ const int* cArray = (colors) ? (int*)colors : NULL;
+ mCanvas->drawVertices(mode, floatCount, vArray, tArray, cArray, indices, indexCount, paint);
+}
+
+SkSurface* SkiaCanvasProxy::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
+ SkDEBUGFAIL("SkiaCanvasProxy::onNewSurface is not supported");
+ return NULL;
+}
+
+void SkiaCanvasProxy::willSave() {
+ mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
+}
+
+SkCanvas::SaveLayerStrategy SkiaCanvasProxy::willSaveLayer(const SkRect* rectPtr,
+ const SkPaint* paint, SaveFlags flags) {
+ SkRect rect;
+ if (rectPtr) {
+ rect = *rectPtr;
+ } else if(!mCanvas->getClipBounds(&rect)) {
+ rect = SkRect::MakeEmpty();
+ }
+ mCanvas->saveLayer(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, paint, flags);
+ return SkCanvas::kNoLayer_SaveLayerStrategy;
+}
+
+void SkiaCanvasProxy::willRestore() {
+ mCanvas->restore();
+}
+
+void SkiaCanvasProxy::didConcat(const SkMatrix& matrix) {
+ mCanvas->concat(matrix);
+}
+
+void SkiaCanvasProxy::didSetMatrix(const SkMatrix& matrix) {
+ mCanvas->setMatrix(matrix);
+}
+
+void SkiaCanvasProxy::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
+ const SkPaint& paint) {
+ SkPath path;
+ path.addRRect(outer);
+ path.addRRect(inner);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ this->drawPath(path, paint);
+}
+
+/**
+ * Utility class that converts the incoming text & paint from the given encoding
+ * into glyphIDs.
+ */
+class GlyphIDConverter {
+public:
+ GlyphIDConverter(const void* text, size_t byteLength, const SkPaint& origPaint) {
+ paint = origPaint;
+ if (paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding) {
+ glyphIDs = (uint16_t*)text;
+ count = byteLength >> 1;
+ } else {
+ storage.reset(byteLength); // ensures space for one glyph per ID given UTF8 encoding.
+ glyphIDs = storage.get();
+ count = paint.textToGlyphs(text, byteLength, storage.get());
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ }
+ }
+
+ SkPaint paint;
+ uint16_t* glyphIDs;
+ int count;
+private:
+ SkAutoSTMalloc<32, uint16_t> storage;
+};
+
+void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint& origPaint) {
+ // convert to glyphIDs if necessary
+ GlyphIDConverter glyphs(text, byteLength, origPaint);
+
+ // compute the glyph positions
+ SkAutoSTMalloc<32, SkPoint> pointStorage(glyphs.count);
+ SkAutoSTMalloc<32, SkScalar> glyphWidths(glyphs.count);
+ glyphs.paint.getTextWidths(glyphs.glyphIDs, glyphs.count << 1, glyphWidths.get());
+
+ // compute conservative bounds
+ // NOTE: We could call the faster paint.getFontBounds for a less accurate,
+ // but even more conservative bounds if this is too slow.
+ SkRect bounds;
+ glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
+
+ // adjust for non-left alignment
+ if (glyphs.paint.getTextAlign() != SkPaint::kLeft_Align) {
+ SkScalar stop = 0;
+ for (int i = 0; i < glyphs.count; i++) {
+ stop += glyphWidths[i];
+ }
+ if (glyphs.paint.getTextAlign() == SkPaint::kCenter_Align) {
+ stop = SkScalarHalf(stop);
+ }
+ if (glyphs.paint.isVerticalText()) {
+ y -= stop;
+ } else {
+ x -= stop;
+ }
+ }
+
+ // setup the first glyph position and adjust bounds if needed
+ if (mCanvas->drawTextAbsolutePos()) {
+ bounds.offset(x,y);
+ pointStorage[0].set(x, y);
+ } else {
+ pointStorage[0].set(0, 0);
+ }
+
+ // setup the remaining glyph positions
+ if (glyphs.paint.isVerticalText()) {
+ for (int i = 1; i < glyphs.count; i++) {
+ pointStorage[i].set(x, glyphWidths[i-1] + pointStorage[i-1].fY);
+ }
+ } else {
+ for (int i = 1; i < glyphs.count; i++) {
+ pointStorage[i].set(glyphWidths[i-1] + pointStorage[i-1].fX, y);
+ }
+ }
+
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ mCanvas->drawText(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint,
+ x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
+}
+
+void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint& origPaint) {
+ // convert to glyphIDs if necessary
+ GlyphIDConverter glyphs(text, byteLength, origPaint);
+
+ // convert to relative positions if necessary
+ int x, y;
+ const SkPoint* posArray;
+ SkAutoSTMalloc<32, SkPoint> pointStorage;
+ if (mCanvas->drawTextAbsolutePos()) {
+ x = 0;
+ y = 0;
+ posArray = pos;
+ } else {
+ x = pos[0].fX;
+ y = pos[0].fY;
+ posArray = pointStorage.reset(glyphs.count);
+ for (int i = 0; i < glyphs.count; i++) {
+ pointStorage[i].fX = pos[i].fX- x;
+ pointStorage[i].fY = pos[i].fY- y;
+ }
+ }
+
+ // compute conservative bounds
+ // NOTE: We could call the faster paint.getFontBounds for a less accurate,
+ // but even more conservative bounds if this is too slow.
+ SkRect bounds;
+ glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
+
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+ mCanvas->drawText(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
+ bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
+}
+
+void SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint& paint) {
+ const size_t pointCount = byteLength >> 1;
+ SkAutoSTMalloc<32, SkPoint> storage(pointCount);
+ SkPoint* pts = storage.get();
+ for (size_t i = 0; i < pointCount; i++) {
+ pts[i].set(xpos[i], constY);
+ }
+ this->onDrawPosText(text, byteLength, pts, paint);
+}
+
+void SkiaCanvasProxy::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint& origPaint) {
+ // convert to glyphIDs if necessary
+ GlyphIDConverter glyphs(text, byteLength, origPaint);
+ mCanvas->drawTextOnPath(glyphs.glyphIDs, glyphs.count, path, 0, 0, glyphs.paint);
+}
+
+void SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ SkDEBUGFAIL("SkiaCanvasProxy::onDrawTextBlob is not supported");
+}
+
+void SkiaCanvasProxy::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
+ SkPatchUtils::VertexData data;
+
+ SkMatrix matrix;
+ mCanvas->getMatrix(&matrix);
+ SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix);
+
+ // It automatically adjusts lodX and lodY in case it exceeds the number of indices.
+ // If it fails to generate the vertices, then we do not draw.
+ if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
+ this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
+ data.fTexCoords, data.fColors, xmode, data.fIndices, data.fIndexCount,
+ paint);
+ }
+}
+
+void SkiaCanvasProxy::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle) {
+ mCanvas->clipRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, op);
+}
+
+void SkiaCanvasProxy::onClipRRect(const SkRRect& roundRect, SkRegion::Op op, ClipEdgeStyle) {
+ SkPath path;
+ path.addRRect(roundRect);
+ mCanvas->clipPath(&path, op);
+}
+
+void SkiaCanvasProxy::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle) {
+ mCanvas->clipPath(&path, op);
+}
+
+void SkiaCanvasProxy::onClipRegion(const SkRegion& region, SkRegion::Op op) {
+ mCanvas->clipRegion(&region, op);
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/SkiaCanvasProxy.h b/libs/hwui/SkiaCanvasProxy.h
new file mode 100644
index 000000000000..4322fcf5edf5
--- /dev/null
+++ b/libs/hwui/SkiaCanvasProxy.h
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+#ifndef SkiaCanvasProxy_DEFINED
+#define SkiaCanvasProxy_DEFINED
+
+#include <cutils/compiler.h>
+#include <SkCanvas.h>
+
+#include "Canvas.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * This class serves as a proxy between Skia's SkCanvas and Android Framework's
+ * Canvas. The class does not maintain any state and will pass through any request
+ * directly to the Canvas provided in the constructor.
+ *
+ * Upon construction it is expected that the provided Canvas has already been
+ * prepared for recording and will continue to be in the recording state while
+ * this proxy class is being used.
+ */
+class ANDROID_API SkiaCanvasProxy : public SkCanvas {
+public:
+ SkiaCanvasProxy(Canvas* canvas);
+ virtual ~SkiaCanvasProxy() {}
+
+protected:
+
+ virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
+
+ virtual void willSave() override;
+ virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
+ virtual void willRestore() override;
+
+ virtual void didConcat(const SkMatrix&) override;
+ virtual void didSetMatrix(const SkMatrix&) override;
+
+ virtual void onDrawPaint(const SkPaint& paint) override;
+ virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[],
+ const SkPaint&) override;
+ virtual void onDrawOval(const SkRect&, const SkPaint&) override;
+ virtual void onDrawRect(const SkRect&, const SkPaint&) override;
+ virtual void onDrawRRect(const SkRRect&, const SkPaint&) override;
+ virtual void onDrawPath(const SkPath& path, const SkPaint&) override;
+ virtual void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
+ const SkPaint*) override;
+ virtual void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst,
+ const SkPaint* paint, DrawBitmapRectFlags flags) override;
+ virtual void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, const SkPaint*) override;
+ virtual void onDrawSprite(const SkBitmap&, int left, int top,
+ const SkPaint*) override;
+ virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
+ const SkPoint texs[], const SkColor colors[], SkXfermode*,
+ const uint16_t indices[], int indexCount,
+ const SkPaint&) override;
+
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
+
+ virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint&) override;
+ virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint&) override;
+ virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint&) override;
+ virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint&) override;
+ virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) override;
+
+ virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode,
+ const SkPaint& paint) override;
+
+ virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
+ virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
+ virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
+ virtual void onClipRegion(const SkRegion&, SkRegion::Op) override;
+
+private:
+ Canvas* mCanvas;
+
+ typedef SkCanvas INHERITED;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // SkiaCanvasProxy_DEFINED