Home | History | Annotate | Download | only in jni
      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