android_view_TextureView.cpp revision b1d90c8f60f71422196c337f1d078b68867f5710
18f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy/*
28f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * Copyright (C) 2011 The Android Open Source Project
38f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy *
48f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
58f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * you may not use this file except in compliance with the License.
68f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * You may obtain a copy of the License at
78f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy *
88f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
98f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy *
108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * Unless required by applicable law or agreed to in writing, software
118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * See the License for the specific language governing permissions and
148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * limitations under the License.
158f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy */
168f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
178f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy#include "jni.h"
188f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy#include <nativehelper/JNIHelp.h>
198f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy#include <android_runtime/AndroidRuntime.h>
20035f1010ebed7d420e74a4e9d830018ab8c8163aRomain Guy#include <android_runtime/android_graphics_SurfaceTexture.h>
218f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
226be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#include <ui/Region.h>
236be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#include <ui/Rect.h>
246be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
25d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden#include <gui/GLConsumer.h>
2652800617946c456e78ed010c82d0ec4358368164Mathias Agopian#include <gui/Surface.h>
276be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
286be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#include <SkBitmap.h>
296be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#include <SkCanvas.h>
308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guynamespace android {
328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy// ----------------------------------------------------------------------------
346be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy// JNI Glue
356be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy// ----------------------------------------------------------------------------
366be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
376be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic struct {
386be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    jmethodID set;
396be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    jfieldID left;
406be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    jfieldID top;
416be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    jfieldID right;
426be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    jfieldID bottom;
436be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy} gRectClassInfo;
446be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
456be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic struct {
46fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    jfieldID mFinalizer;
47fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    jfieldID mNativeCanvas;
48fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    jfieldID mSurfaceFormat;
496be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy} gCanvasClassInfo;
506be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
516be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic struct {
52fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    jfieldID mNativeCanvas;
53fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger} gCanvasFinalizerClassInfo;
54fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger
55fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenbergerstatic struct {
566be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    jfieldID nativeWindow;
576be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy} gTextureViewClassInfo;
586be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
596be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#define GET_INT(object, field) \
606be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    env->GetIntField(object, field)
616be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
626be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#define SET_INT(object, field, value) \
636be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    env->SetIntField(object, field, value)
646be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
656be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#define INVOKEV(object, method, ...) \
666be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    env->CallVoidMethod(object, method, __VA_ARGS__)
676be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
686be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy// ----------------------------------------------------------------------------
698f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy// Native layer
708f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy// ----------------------------------------------------------------------------
718f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
728f0095cd33558e9cc8a440047908e53b68906f5fRomain Guystatic void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject,
73035f1010ebed7d420e74a4e9d830018ab8c8163aRomain Guy    jobject surface, jint width, jint height) {
748f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
75d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> glConsumer(SurfaceTexture_getSurfaceTexture(env, surface));
76d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    glConsumer->setDefaultBufferSize(width, height);
778f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy}
788f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
796be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic inline SkBitmap::Config convertPixelFormat(int32_t format) {
806be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    switch (format) {
816be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        case WINDOW_FORMAT_RGBA_8888:
826be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            return SkBitmap::kARGB_8888_Config;
836be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        case WINDOW_FORMAT_RGBX_8888:
846be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            return SkBitmap::kARGB_8888_Config;
856be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        case WINDOW_FORMAT_RGB_565:
866be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            return SkBitmap::kRGB_565_Config;
876be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        default:
886be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            return SkBitmap::kNo_Config;
896be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    }
906be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy}
916be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
926be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy/**
936be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * This is a private API, and this implementation is also provided in the NDK.
946be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * However, the NDK links against android_runtime, which means that using the
956be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * NDK implementation would create a circular dependency between the libraries.
966be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy */
976be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic int32_t native_window_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
986be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        Rect* inOutDirtyBounds) {
996be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    return window->perform(window, NATIVE_WINDOW_LOCK, outBuffer, inOutDirtyBounds);
1006be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy}
1016be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1026be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic int32_t native_window_unlockAndPost(ANativeWindow* window) {
1036be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    return window->perform(window, NATIVE_WINDOW_UNLOCK_AND_POST);
1046be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy}
1056be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1066be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic void android_view_TextureView_createNativeWindow(JNIEnv* env, jobject textureView,
1076be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        jobject surface) {
1086be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
109d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> glConsumer(SurfaceTexture_getSurfaceTexture(env, surface));
11052800617946c456e78ed010c82d0ec4358368164Mathias Agopian    sp<ANativeWindow> window = new Surface(glConsumer->getBufferQueue());
1116be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
112b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian    window->incStrong((void*)android_view_TextureView_createNativeWindow);
1136be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    SET_INT(textureView, gTextureViewClassInfo.nativeWindow, jint(window.get()));
1146be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy}
1156be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1166be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic void android_view_TextureView_destroyNativeWindow(JNIEnv* env, jobject textureView) {
1176be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1186be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    ANativeWindow* nativeWindow = (ANativeWindow*)
1196be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            GET_INT(textureView, gTextureViewClassInfo.nativeWindow);
1206be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1216be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    if (nativeWindow) {
1226be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        sp<ANativeWindow> window(nativeWindow);
123b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian            window->decStrong((void*)android_view_TextureView_createNativeWindow);
1246be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        SET_INT(textureView, gTextureViewClassInfo.nativeWindow, 0);
1256be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    }
1266be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy}
1276be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
128fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenbergerstatic inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) {
129fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger  jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
130fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger  SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
131fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger          env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas));
132fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger  env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas);
133fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger  env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas);
134fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger  SkSafeUnref(previousCanvas);
135fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger}
136fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger
1376be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic void android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
1386be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        jint nativeWindow, jobject canvas, jobject dirtyRect) {
1396be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1406be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    if (!nativeWindow) {
1416be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        return;
1426be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    }
1436be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1446be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    ANativeWindow_Buffer buffer;
1456be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1466be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    Rect rect;
1476be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    if (dirtyRect) {
1486be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        rect.left = GET_INT(dirtyRect, gRectClassInfo.left);
1496be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        rect.top = GET_INT(dirtyRect, gRectClassInfo.top);
1506be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        rect.right = GET_INT(dirtyRect, gRectClassInfo.right);
1516be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        rect.bottom = GET_INT(dirtyRect, gRectClassInfo.bottom);
1526be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    } else {
1536be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        rect.set(Rect(0x3FFF, 0x3FFF));
1546be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    }
1556be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1566be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
1576be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    native_window_lock(window.get(), &buffer, &rect);
1586be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1596be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    ssize_t bytesCount = buffer.stride * bytesPerPixel(buffer.format);
1606be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1616be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    SkBitmap bitmap;
1626be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    bitmap.setConfig(convertPixelFormat(buffer.format), buffer.width, buffer.height, bytesCount);
1636be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1646be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    if (buffer.format == WINDOW_FORMAT_RGBX_8888) {
1656be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        bitmap.setIsOpaque(true);
1666be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    }
1676be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1686be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    if (buffer.width > 0 && buffer.height > 0) {
1696be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        bitmap.setPixels(buffer.bits);
1706be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    } else {
1716be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        bitmap.setPixels(NULL);
1726be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    }
1736be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
174fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer.format);
175fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger
176fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
177fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    swapCanvasPtr(env, canvas, nativeCanvas);
1786be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1796be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    SkRect clipRect;
1806be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    clipRect.set(rect.left, rect.top, rect.right, rect.bottom);
1816be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    nativeCanvas->clipRect(clipRect);
1826be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1836be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    if (dirtyRect) {
1846be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        INVOKEV(dirtyRect, gRectClassInfo.set,
1856be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy                int(rect.left), int(rect.top), int(rect.right), int(rect.bottom));
1866be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    }
1876be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy}
1886be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1896be3d5561cbeccf0a8257a4acb155657f868e548Romain Guystatic void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject,
1906be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        jint nativeWindow, jobject canvas) {
1916be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
192fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    SkCanvas* nativeCanvas = SkNEW(SkCanvas);
193fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    swapCanvasPtr(env, canvas, nativeCanvas);
1946be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
1956be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    if (nativeWindow) {
1966be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
1976be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        native_window_unlockAndPost(window.get());
1986be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    }
1996be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy}
2006be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2018f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy// ----------------------------------------------------------------------------
2028f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy// JNI Glue
2038f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy// ----------------------------------------------------------------------------
2048f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2058f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyconst char* const kClassPathName = "android/view/TextureView";
2068f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2078f0095cd33558e9cc8a440047908e53b68906f5fRomain Guystatic JNINativeMethod gMethods[] = {
208035f1010ebed7d420e74a4e9d830018ab8c8163aRomain Guy    {   "nSetDefaultBufferSize", "(Landroid/graphics/SurfaceTexture;II)V",
2096be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            (void*) android_view_TextureView_setDefaultBufferSize },
2106be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2116be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    {   "nCreateNativeWindow", "(Landroid/graphics/SurfaceTexture;)V",
2126be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            (void*) android_view_TextureView_createNativeWindow },
2136be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    {   "nDestroyNativeWindow", "()V",
2146be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            (void*) android_view_TextureView_destroyNativeWindow },
2156be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2166be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    {   "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V",
2176be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            (void*) android_view_TextureView_lockCanvas },
2186be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    {   "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
2196be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy            (void*) android_view_TextureView_unlockCanvasAndPost },
2208f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy};
2218f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2226be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#define FIND_CLASS(var, className) \
2236be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        var = env->FindClass(className); \
2246be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        LOG_FATAL_IF(!var, "Unable to find class " className);
2256be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2266be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
2276be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
2286be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        LOG_FATAL_IF(!var, "Unable to find method " methodName);
2296be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2306be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
2316be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
2326be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy        LOG_FATAL_IF(!var, "Unable to find field" fieldName);
2336be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyint register_android_view_TextureView(JNIEnv* env) {
2356be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    jclass clazz;
2366be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    FIND_CLASS(clazz, "android/graphics/Rect");
2376be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
2386be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I");
2396be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I");
2406be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I");
2416be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");
2426be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2436be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    FIND_CLASS(clazz, "android/graphics/Canvas");
244fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;");
245fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
246fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");
247fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger
248fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer");
249fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger    GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
2506be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2516be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    FIND_CLASS(clazz, "android/view/TextureView");
2526be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    GET_FIELD_ID(gTextureViewClassInfo.nativeWindow, clazz, "mNativeWindow", "I");
2536be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy
2548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
2558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy}
2568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy};
258