Index: platform_tools/android/apps/canvasproof/src/main/jni/org_skia_canvasproof_GaneshPictureRenderer.cpp |
diff --git a/platform_tools/android/apps/canvasproof/src/main/jni/org_skia_canvasproof_GaneshPictureRenderer.cpp b/platform_tools/android/apps/canvasproof/src/main/jni/org_skia_canvasproof_GaneshPictureRenderer.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d1de529674104e39e6853e53c9d50c6e50e2ac84 |
--- /dev/null |
+++ b/platform_tools/android/apps/canvasproof/src/main/jni/org_skia_canvasproof_GaneshPictureRenderer.cpp |
@@ -0,0 +1,146 @@ |
+/* |
+ * Copyright 2015 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "org_skia_canvasproof_GaneshPictureRenderer.h" |
+ |
+#include "GrContext.h" |
+#include "JavaInputStream.h" |
+#include "SkCanvas.h" |
+#include "SkMatrix.h" |
+#include "SkPicture.h" |
+#include "SkRect.h" |
+#include "SkStream.h" |
+#include "SkSurface.h" |
+ |
+#define TAG "GaneshPictureRenderer.cpp: " |
+ |
+static void render_picture(GrContext* grContext, |
+ int width, |
+ int height, |
+ const SkPicture* picture, |
+ const SkMatrix& matrix) { |
+ SkASSERT(grContext); |
+ if (!picture) { |
+ SkDebugf(TAG "!picture\n"); |
+ return; |
+ } |
+ // Render to the default framebuffer render target. |
+ GrBackendRenderTargetDesc desc; |
+ desc.fWidth = width; |
+ desc.fHeight = height; |
+ desc.fConfig = kSkia8888_GrPixelConfig; |
+ desc.fOrigin = kBottomLeft_GrSurfaceOrigin; |
+ SkSurfaceProps surfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag, |
+ kUnknown_SkPixelGeometry); |
+ // TODO: Check to see if we can keep the surface between draw calls. |
+ SkAutoTUnref<SkSurface> surface( |
+ SkSurface::NewFromBackendRenderTarget( |
+ grContext, desc, &surfaceProps)); |
+ if (surface) { |
+ SkCanvas* canvas = surface->getCanvas(); |
+ SkASSERT(canvas); |
+ canvas->clear(SK_ColorGRAY); |
+ canvas->concat(matrix); |
+ SkRect cullRect = picture->cullRect(); |
+ canvas->clipRect(cullRect); |
+ picture->playback(canvas); |
+ canvas->flush(); |
+ } |
+} |
+ |
+namespace { |
+struct GaneshPictureRendererImpl { |
+ SkAutoTUnref<GrContext> fGrContext; |
+ void render(int w, int h, const SkPicture* p, const SkMatrix& m) { |
+ if (!fGrContext) { |
+ // Cache the rendering context between frames. |
+ fGrContext.reset(GrContext::Create(kOpenGL_GrBackend, 0)); |
+ if (!fGrContext) { |
+ SkDebugf(TAG "GrContext::Create - failed\n"); |
+ return; |
+ } |
+ } |
+ render_picture(fGrContext, w, h, p, m); |
+ } |
+}; |
+} // namespace |
+ |
+/* |
+ * Class: org_skia_canvasproof_GaneshPictureRenderer |
+ * Method: DrawThisFrame |
+ * Signature: (IIFJ)V |
+ */ |
+JNIEXPORT void JNICALL Java_org_skia_canvasproof_GaneshPictureRenderer_DrawThisFrame( |
+ JNIEnv*, jclass, jint width, jint height, jfloat scale, jlong ptr, jlong pic) { |
+ if (!ptr) { return; } |
+ SkMatrix matrix = SkMatrix::MakeScale((SkScalar)scale); |
+ GaneshPictureRendererImpl* impl = |
+ reinterpret_cast<GaneshPictureRendererImpl*>(ptr); |
+ SkPicture* picture = reinterpret_cast<SkPicture*>(pic); |
+ impl->render((int)width, (int)height, picture, matrix); |
+} |
+ |
+/* |
+ * Class: org_skia_canvasproof_GaneshPictureRenderer |
+ * Method: Ctor |
+ * Signature: ()J |
+ */ |
+JNIEXPORT jlong JNICALL Java_org_skia_canvasproof_GaneshPictureRenderer_Ctor |
+ (JNIEnv *, jclass) { |
+ return reinterpret_cast<jlong>(new GaneshPictureRendererImpl); |
+} |
+ |
+/* |
+ * Class: org_skia_canvasproof_GaneshPictureRenderer |
+ * Method: CleanUp |
+ * Signature: (J)V |
+ */ |
+JNIEXPORT void JNICALL Java_org_skia_canvasproof_GaneshPictureRenderer_CleanUp |
+ (JNIEnv *, jclass, jlong ptr) { |
+ delete reinterpret_cast<GaneshPictureRendererImpl*>(ptr); |
+} |
+ |
+namespace { |
+struct AndroidRectHelper { |
+ jfieldID fLeft, fTop, fRight, fBottom; |
+ AndroidRectHelper() |
+ : fLeft(nullptr), fTop(nullptr), fRight(nullptr), fBottom(nullptr) {} |
+ void config(JNIEnv *env) { |
+ if (!fLeft) { |
+ jclass rectClass = env->FindClass("android/graphics/Rect"); |
+ SkASSERT(rectClass); |
+ fLeft = env->GetFieldID(rectClass, "left", "I"); |
+ fTop = env->GetFieldID(rectClass, "top", "I"); |
+ fRight = env->GetFieldID(rectClass, "right", "I"); |
+ fBottom = env->GetFieldID(rectClass, "bottom", "I"); |
+ } |
+ } |
+}; |
+} // namespace |
+ |
+/* |
+ * Class: org_skia_canvasproof_GaneshPictureRenderer |
+ * Method: GetCullRect |
+ * Signature: (Landroid/graphics/Rect;J)V |
+ */ |
+JNIEXPORT void JNICALL Java_org_skia_canvasproof_GaneshPictureRenderer_GetCullRect |
+ (JNIEnv *env, jclass, jobject androidGraphicsRect, jlong picturePtr) { |
+ SkASSERT(androidGraphicsRect); |
+ const SkPicture* picture = reinterpret_cast<SkPicture*>(picturePtr); |
+ SkRect rect = SkRect::MakeEmpty(); |
+ if (picture) { |
+ rect = picture->cullRect(); |
+ } |
+ SkIRect iRect; |
+ rect.roundOut(&iRect); |
+ static AndroidRectHelper help; |
+ help.config(env); |
+ env->SetIntField(androidGraphicsRect, help.fLeft, (jint)(iRect.left())); |
+ env->SetIntField(androidGraphicsRect, help.fTop, (jint)(iRect.top())); |
+ env->SetIntField(androidGraphicsRect, help.fRight, (jint)(iRect.right())); |
+ env->SetIntField(androidGraphicsRect, help.fBottom, (jint)(iRect.bottom())); |
+} |