1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "org_skia_canvasproof_GaneshPictureRenderer.h" 9 10 #include "GrContext.h" 11 #include "JavaInputStream.h" 12 #include "SkCanvas.h" 13 #include "SkMatrix.h" 14 #include "SkPicture.h" 15 #include "SkRect.h" 16 #include "SkStream.h" 17 #include "SkSurface.h" 18 19 #define TAG "GaneshPictureRenderer.cpp: " 20 21 static void render_picture(GrContext* grContext, 22 int width, 23 int height, 24 const SkPicture* picture, 25 const SkMatrix& matrix) { 26 SkASSERT(grContext); 27 if (!picture) { 28 SkDebugf(TAG "!picture\n"); 29 return; 30 } 31 // Render to the default framebuffer render target. 32 GrBackendRenderTargetDesc desc; 33 desc.fWidth = width; 34 desc.fHeight = height; 35 desc.fConfig = kSkia8888_GrPixelConfig; 36 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; 37 SkSurfaceProps surfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag, 38 kUnknown_SkPixelGeometry); 39 // TODO: Check to see if we can keep the surface between draw calls. 40 SkAutoTUnref<SkSurface> surface( 41 SkSurface::NewFromBackendRenderTarget( 42 grContext, desc, &surfaceProps)); 43 if (surface) { 44 SkCanvas* canvas = surface->getCanvas(); 45 SkASSERT(canvas); 46 canvas->clear(SK_ColorGRAY); 47 canvas->concat(matrix); 48 SkRect cullRect = picture->cullRect(); 49 canvas->clipRect(cullRect); 50 picture->playback(canvas); 51 canvas->flush(); 52 } 53 } 54 55 namespace { 56 struct GaneshPictureRendererImpl { 57 SkAutoTUnref<GrContext> fGrContext; 58 void render(int w, int h, const SkPicture* p, const SkMatrix& m) { 59 if (!fGrContext) { 60 // Cache the rendering context between frames. 61 fGrContext.reset(GrContext::Create(kOpenGL_GrBackend, 0)); 62 if (!fGrContext) { 63 SkDebugf(TAG "GrContext::Create - failed\n"); 64 return; 65 } 66 } 67 render_picture(fGrContext, w, h, p, m); 68 } 69 }; 70 } // namespace 71 72 /* 73 * Class: org_skia_canvasproof_GaneshPictureRenderer 74 * Method: DrawThisFrame 75 * Signature: (IIFJ)V 76 */ 77 JNIEXPORT void JNICALL Java_org_skia_canvasproof_GaneshPictureRenderer_DrawThisFrame( 78 JNIEnv*, jclass, jint width, jint height, jfloat scale, jlong ptr, jlong pic) { 79 if (!ptr) { return; } 80 SkMatrix matrix = SkMatrix::MakeScale((SkScalar)scale); 81 GaneshPictureRendererImpl* impl = 82 reinterpret_cast<GaneshPictureRendererImpl*>(ptr); 83 SkPicture* picture = reinterpret_cast<SkPicture*>(pic); 84 impl->render((int)width, (int)height, picture, matrix); 85 } 86 87 /* 88 * Class: org_skia_canvasproof_GaneshPictureRenderer 89 * Method: Ctor 90 * Signature: ()J 91 */ 92 JNIEXPORT jlong JNICALL Java_org_skia_canvasproof_GaneshPictureRenderer_Ctor 93 (JNIEnv *, jclass) { 94 return reinterpret_cast<jlong>(new GaneshPictureRendererImpl); 95 } 96 97 /* 98 * Class: org_skia_canvasproof_GaneshPictureRenderer 99 * Method: CleanUp 100 * Signature: (J)V 101 */ 102 JNIEXPORT void JNICALL Java_org_skia_canvasproof_GaneshPictureRenderer_CleanUp 103 (JNIEnv *, jclass, jlong ptr) { 104 delete reinterpret_cast<GaneshPictureRendererImpl*>(ptr); 105 } 106 107 namespace { 108 struct AndroidRectHelper { 109 jfieldID fLeft, fTop, fRight, fBottom; 110 AndroidRectHelper() 111 : fLeft(nullptr), fTop(nullptr), fRight(nullptr), fBottom(nullptr) {} 112 void config(JNIEnv *env) { 113 if (!fLeft) { 114 jclass rectClass = env->FindClass("android/graphics/Rect"); 115 SkASSERT(rectClass); 116 fLeft = env->GetFieldID(rectClass, "left", "I"); 117 fTop = env->GetFieldID(rectClass, "top", "I"); 118 fRight = env->GetFieldID(rectClass, "right", "I"); 119 fBottom = env->GetFieldID(rectClass, "bottom", "I"); 120 } 121 } 122 }; 123 } // namespace 124 125 /* 126 * Class: org_skia_canvasproof_GaneshPictureRenderer 127 * Method: GetCullRect 128 * Signature: (Landroid/graphics/Rect;J)V 129 */ 130 JNIEXPORT void JNICALL Java_org_skia_canvasproof_GaneshPictureRenderer_GetCullRect 131 (JNIEnv *env, jclass, jobject androidGraphicsRect, jlong picturePtr) { 132 SkASSERT(androidGraphicsRect); 133 const SkPicture* picture = reinterpret_cast<SkPicture*>(picturePtr); 134 SkRect rect = SkRect::MakeEmpty(); 135 if (picture) { 136 rect = picture->cullRect(); 137 } 138 SkIRect iRect; 139 rect.roundOut(&iRect); 140 static AndroidRectHelper help; 141 help.config(env); 142 env->SetIntField(androidGraphicsRect, help.fLeft, (jint)(iRect.left())); 143 env->SetIntField(androidGraphicsRect, help.fTop, (jint)(iRect.top())); 144 env->SetIntField(androidGraphicsRect, help.fRight, (jint)(iRect.right())); 145 env->SetIntField(androidGraphicsRect, help.fBottom, (jint)(iRect.bottom())); 146 } 147