android_view_Surface.cpp revision ffddc9b8045235a493ec506965ae4892601eb23d
18be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy/*
26cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy * Copyright (C) 2007 The Android Open Source Project
36cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy *
46cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy * Licensed under the Apache License, Version 2.0 (the "License");
56cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy * you may not use this file except in compliance with the License.
66cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy * You may obtain a copy of the License at
78be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy *
88be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy *      http://www.apache.org/licenses/LICENSE-2.0
96cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy *
106cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy * Unless required by applicable law or agreed to in writing, software
116cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy * distributed under the License is distributed on an "AS IS" BASIS,
126cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy * See the License for the specific language governing permissions and
148be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy * limitations under the License.
156cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy */
168be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
176cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#define LOG_TAG "Surface"
186cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
198be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include <stdio.h>
208be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
216cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include "jni.h"
226cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include "JNIHelp.h"
238be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include "android_os_Parcel.h"
248be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include "android/graphics/GraphicsJNI.h"
256cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
266cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include <android_runtime/AndroidRuntime.h>
278be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include <android_runtime/android_view_Surface.h>
286cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include <android_runtime/android_graphics_SurfaceTexture.h>
298be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
306cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include <gui/Surface.h>
318be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include <gui/SurfaceControl.h>
328be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include <gui/GLConsumer.h>
336cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
346cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include <ui/Rect.h>
356cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include <ui/Region.h>
368be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
378be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include <SkCanvas.h>
386cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include <SkBitmap.h>
396cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include <SkRegion.h>
406cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
418be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include <utils/misc.h>
428be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy#include <utils/Log.h>
436cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
446cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy#include <ScopedUtfChars.h>
456cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
468be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy// ----------------------------------------------------------------------------
478be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
486cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphynamespace android {
496cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
506cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic const char* const OutOfResourcesException =
518be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    "android/view/Surface$OutOfResourcesException";
528be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
536cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic struct {
546cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jclass clazz;
556cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jfieldID mNativeObject;
568be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    jfieldID mGenerationId;
578be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    jfieldID mCanvas;
586cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jmethodID ctor;
596cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy} gSurfaceClassInfo;
606cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
618be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphystatic struct {
628be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    jfieldID left;
636cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jfieldID top;
646cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jfieldID right;
656cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jfieldID bottom;
668be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy} gRectClassInfo;
678be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
686cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic struct {
696cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jfieldID mFinalizer;
706cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jfieldID mNativeCanvas;
718be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    jfieldID mSurfaceFormat;
728be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy} gCanvasClassInfo;
736cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
746cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic struct {
756cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jfieldID mNativeCanvas;
768be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy} gCanvasFinalizerClassInfo;
778be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
786cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy// ----------------------------------------------------------------------------
796cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
806cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphybool android_view_Surface_isInstanceOf(JNIEnv* env, jobject obj) {
818be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    return env->IsInstanceOf(obj, gSurfaceClassInfo.clazz);
828be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy}
836cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
846cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphysp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) {
856cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return android_view_Surface_getSurface(env, surfaceObj);
868be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy}
878be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
886cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphysp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) {
896cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return reinterpret_cast<Surface *>(
906cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeObject));
918be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy}
928be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
936cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphyjobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env,
946cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        const sp<IGraphicBufferProducer>& bufferProducer) {
956cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (bufferProducer == NULL) {
968be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        return NULL;
978be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    }
986cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
996cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    sp<Surface> surface(new Surface(bufferProducer));
1006cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (surface == NULL) {
1018be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        return NULL;
1028be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    }
1036cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1046cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, gSurfaceClassInfo.ctor, surface.get());
1056cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (surfaceObj == NULL) {
1068be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        if (env->ExceptionCheck()) {
1078be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy            ALOGE("Could not create instance of Surface from IGraphicBufferProducer.");
1086cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            LOGE_EX(env);
1096cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            env->ExceptionClear();
1106cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        }
1118be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        return NULL;
1128be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    }
1136cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    surface->incStrong(surfaceObj);
1146cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return surfaceObj;
1156cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
1168be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
1178be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy// ----------------------------------------------------------------------------
1186cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1196cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic inline bool isSurfaceValid(const sp<Surface>& sur) {
1206cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return Surface::isValid(sur);
1218be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy}
1228be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
1236cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy// ----------------------------------------------------------------------------
1246cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1256cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic jint nativeCreateFromSurfaceTexture(JNIEnv* env, jclass clazz,
1268be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        jobject surfaceTextureObj) {
1278be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    sp<GLConsumer> st(SurfaceTexture_getSurfaceTexture(env, surfaceTextureObj));
1286cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (st == NULL) {
1296cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        jniThrowException(env, "java/lang/IllegalArgumentException",
1306cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy                "SurfaceTexture has already been released");
1318be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        return 0;
1328be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    }
1336cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1346cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    sp<IGraphicBufferProducer> bq = st->getBufferQueue();
1356cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    sp<Surface> surface(new Surface(bq));
1368be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    if (surface == NULL) {
1378be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        jniThrowException(env, OutOfResourcesException, NULL);
1386cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        return 0;
1396cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
1406cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1418be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    surface->incStrong(clazz);
1428be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    return int(surface.get());
1436cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
1446cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1456cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic void nativeRelease(JNIEnv* env, jclass clazz, jint nativeObject) {
1468be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
1478be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    sur->decStrong(clazz);
1486cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
1496cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1506cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic void nativeDestroy(JNIEnv* env, jclass clazz, jint nativeObject) {
1518be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
1528be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    sur->decStrong(clazz);
1536cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
1546cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1556cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic jboolean nativeIsValid(JNIEnv* env, jclass clazz, jint nativeObject) {
1568be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
1578be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    return isSurfaceValid(sur) ? JNI_TRUE : JNI_FALSE;
1586cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
1596cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1606cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jclass clazz, jint nativeObject) {
1618be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
1628be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    if (!isSurfaceValid(sur)) {
1636cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        doThrowIAE(env);
1646cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        return JNI_FALSE;
1656cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
1668be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    int value = 0;
1678be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    ANativeWindow* anw = static_cast<ANativeWindow*>(sur.get());
1686cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    anw->query(anw, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value);
1696cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return value;
1706cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
1718be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
1728be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphystatic inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
1736cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
1746cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        we can map to SkBitmap::kARGB_8888_Config, and optionally call
1756cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
1768be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    */
1778be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    switch (format) {
1786cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
1796cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
1806cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    case PIXEL_FORMAT_RGBA_4444:    return SkBitmap::kARGB_4444_Config;
1818be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
1828be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    case PIXEL_FORMAT_A_8:          return SkBitmap::kA8_Config;
1836cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    default:                        return SkBitmap::kNo_Config;
1846cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
1856cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
1868be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
1878be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphystatic inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) {
1886cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy  jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
1896cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy  SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
1906cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy          env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas));
1918be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy  env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas);
1928be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy  env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas);
1936cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy  SkSafeUnref(previousCanvas);
1946cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
1956cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1968be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphystatic jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jint nativeObject, jobject dirtyRectObj) {
1978be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
1986cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
1996cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (!isSurfaceValid(surface)) {
2006cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        doThrowIAE(env);
2018be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        return NULL;
2028be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    }
2036cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2046cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    // get dirty region
2056cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    Region dirtyRegion;
2068be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    if (dirtyRectObj) {
2078be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        Rect dirty;
2086cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        dirty.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
2096cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        dirty.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
2106cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        dirty.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
2118be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        dirty.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
2128be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        if (!dirty.isEmpty()) {
2136cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            dirtyRegion.set(dirty);
2146cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        }
2156cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    } else {
2168be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        dirtyRegion.set(Rect(0x3FFF, 0x3FFF));
2178be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    }
2186cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2196cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    ANativeWindow_Buffer outBuffer;
2206cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    Rect dirtyBounds(dirtyRegion.getBounds());
2218be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    status_t err = surface->lock(&outBuffer, &dirtyBounds);
2228be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    dirtyRegion.set(dirtyBounds);
2236cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (err < 0) {
2246cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        const char* const exception = (err == NO_MEMORY) ?
2256cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy                OutOfResourcesException :
2268be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy                "java/lang/IllegalArgumentException";
2278be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        jniThrowException(env, exception, NULL);
2286cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        return NULL;
2296cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
2306cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2318be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    // Associate a SkCanvas object to this surface
2328be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    jobject canvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas);
2336cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    env->SetIntField(canvasObj, gCanvasClassInfo.mSurfaceFormat, outBuffer.format);
2346cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2356cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    SkBitmap bitmap;
2368be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
2378be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    bitmap.setConfig(convertPixelFormat(outBuffer.format), outBuffer.width, outBuffer.height, bpr);
2386cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) {
2396cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        bitmap.setIsOpaque(true);
2406cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
2418be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    if (outBuffer.width > 0 && outBuffer.height > 0) {
2428be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        bitmap.setPixels(outBuffer.bits);
2436cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    } else {
2446cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        // be safe with an empty bitmap.
2456cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        bitmap.setPixels(NULL);
2466cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
2478be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
2488be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
2496cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    swapCanvasPtr(env, canvasObj, nativeCanvas);
2506cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2516cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    SkRegion clipReg;
2526cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (dirtyRegion.isRect()) { // very common case
2536cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        const Rect b(dirtyRegion.getBounds());
2546�u��{$�P�        clipReg.setRect(b.left, b.top, b.right, b.bottom);
255jYY���d�ݲ��uų�j�&i�c���i�Hs���|�R��    } else {
256O�Ȃ=����Vx>���{��f#l�`��e:        size_t count;
2576cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        Rect const* r = dirtyRegion.getArray(&count);
2586cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        while (count) {
2596cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op);
2606cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            r++, count--;
2616cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        }
262Yb�D    }
2636cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
264Y1M/;�K�    nativeCanvas->clipRegion(clipReg);
2656cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2666cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (dirtyRectObj) {
267y�&�W��/S�~)��qUѾ        const Rect& bounds(dirtyRegion.getBounds());
268Y�d�RK�        env->SetIntField(dirtyRectObj, gRectClassInfo.left, bounds.left);
2696cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        env->SetIntField(dirtyRectObj, gRectClassInfo.top, bounds.top);
2706cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        env->SetIntField(dirtyRectObj, gRectClassInfo.right, bounds.right);
2716cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, bounds.bottom);
272eP�h�    }
2736cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2746cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return canvasObj;
2756cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
2766cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2776cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jint nativeObject, jobject canvasObj) {
2786cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jobject ownCanvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas);
2796cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (!env->IsSameObject(ownCanvasObj, canvasObj)) {
2808be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy        doThrowIAE(env);
2816cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        return;
2826cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
2836cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2846cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
2856cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (!isSurfaceValid(surface)) {
2866cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        return;
2876cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
2886cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
2896cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    // detach the canvas from the surface
2906cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    SkCanvas* nativeCanvas = SkNEW(SkCanvas);
2918be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy    swapCanvasPtr(env, canvasObj, nativeCanvas);
2928be054358ca53437fc3dd3889ec496a5f1ea9a5cClay Murphy
2936cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    // unlock surface
2946cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    status_t err = surface->unlockAndPost();
2956cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (err < 0) {
2966cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        doThrowIAE(env);
2976cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
2986cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
2996cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3006cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy// ----------------------------------------------------------------------------
3016cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3026cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic jint nativeCopyFrom(JNIEnv* env, jclass clazz,
3036cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        jint nativeObject, jint surfaceControlNativeObj) {
304Ox�Q��G"�ŷ����b��.O�_���t�b؆���Y�f���!A��?��!Ŷ��q�k    /*
3056cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy     * This is used by the WindowManagerService just after constructing
3066cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy     * a Surface and is necessary for returning the Surface reference to
3076cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy     * the caller. At this point, we should only have a SurfaceControl.
3086cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy     */
3096cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
310Z�m<Vtb)_utB�ׅX���@�L�	�K_��+�d�����M�y��i�P�YY����(���$gf��_��+m��Oe�+=E`�_���	����{?��A�XdPT�G���D<*���*�{n    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
3116cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    sp<Surface> other(ctrl->getSurface());
3126cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (other != NULL) {
3136cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        other->incStrong(clazz);
3146cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
3156cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3166cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
3176cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (sur != NULL) {
3186cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        sur->decStrong(clazz);
3196cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
3206cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3216cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return int(other.get());
3226cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
323k�b�.�#F��n��\��Y�[:̔�F�|$h
3246cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic jint nativeReadFromParcel(JNIEnv* env, jclass clazz,
3256cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        jint nativeObject, jobject parcelObj) {
3266cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    Parcel* parcel = parcelForJavaObject(env, parcelObj);
3276cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (parcel == NULL) {
3286cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        doThrowNPE(env);
3296cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        return 0;
3306cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    }
331v[�)+��̖��a� 釋c�����    sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
3326cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (self != NULL) {
3336cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        self->decStrong(clazz);
334W�g��Y[�sH� d�THZh�$�%    }
3356cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    sp<Surface> sur(Surface::readFromParcel(*parcel));
3366cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (sur != NULL) {
3376cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        sur->incStrong(clazz);
3385�D�dOV:w    }
3396cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return int(sur.get());
3406cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
3416cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3426cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic void nativeWriteToParcel(JNIEnv* env, jclass clazz,
3436cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        jint nativeObject, jobject parcelObj) {
3446cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    Parcel* parcel = parcelForJavaObject(env, parcelObj);
3456cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    if (parcel == NULL) {
3466cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        doThrowNPE(env);
3476cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy        return;
348N    }
349NL~    sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
350Mq��L(z    Surface::writeToParcel(self, parcel);
351F�׉}
352oZ�Ɂ�:̑δx��
3536cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy// ----------------------------------------------------------------------------
3546cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3556cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphystatic JNINativeMethod gSurfaceMethods[] = {
3566cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)I",
3576cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            (void*)nativeCreateFromSurfaceTexture },
3586cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeRelease", "(I)V",
359l0�P�Z��I�k�K���FH���V|���J+            (void*)nativeRelease },
3606cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeDestroy", "(I)V",
3616cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            (void*)nativeDestroy },
3626cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeIsValid", "(I)Z",
3636cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            (void*)nativeIsValid },
3646cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeIsConsumerRunningBehind", "(I)Z",
3656cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            (void*)nativeIsConsumerRunningBehind },
3666cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeLockCanvas", "(ILandroid/graphics/Rect;)Landroid/graphics/Canvas;",
3676cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            (void*)nativeLockCanvas },
3686cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
369L�rvJ�i            (void*)nativeUnlockCanvasAndPost },
3706cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeCopyFrom", "(II)I",
3716cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            (void*)nativeCopyFrom },
3726cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    {"nativeReadFromParcel", "(ILandroid/os/Parcel;)I",
3732Nj��RО,Ĭ.�'�����R��            (void*)nativeReadFromParcel },
374GAJr��I��B    {"nativeWriteToParcel", "(ILandroid/os/Parcel;)V",
3756cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            (void*)nativeWriteToParcel },
3766cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy};
3776cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3786cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphyint register_android_view_Surface(JNIEnv* env)
379Ky�^��{
3806cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    int err = AndroidRuntime::registerNativeMethods(env, "android/view/Surface",
3816cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            gSurfaceMethods, NELEM(gSurfaceMethods));
3826cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3836cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    jclass clazz = env->FindClass("android/view/Surface");
384_�w���)AgA��m���=N    gSurfaceClassInfo.clazz = jclass(env->NewGlobalRef(clazz));
3856cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    gSurfaceClassInfo.mNativeObject =
386RFSG�@�            env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeObject", "I");
3876cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    gSurfaceClassInfo.mGenerationId =
3886cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            env->GetFieldID(gSurfaceClassInfo.clazz, "mGenerationId", "I");
3896cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    gSurfaceClassInfo.mCanvas =
3906cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy            env->GetFieldID(gSurfaceClassInfo.clazz, "mCanvas", "Landroid/graphics/Canvas;");
391i�,�BT���rxvw�$A����V�|�g�φ��X��>Ւ)�zacv=*    gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "(I)V");
3926cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
3936cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    clazz = env->FindClass("android/graphics/Canvas");
394R$��J�e�GE����IS� lY    gCanvasClassInfo.mFinalizer = env->GetFieldID(clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;");
3956cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    gCanvasClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "I");
3966cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    gCanvasClassInfo.mSurfaceFormat = env->GetFieldID(clazz, "mSurfaceFormat", "I");
3971���՝�i}�z�_m���H�]�m����SXE
3986cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    clazz = env->FindClass("android/graphics/Canvas$CanvasFinalizer");
3996cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    gCanvasFinalizerClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "I");
4006cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
401S_������"�g��J&*���x�FAj����w����׳�%�    clazz = env->FindClass("android/graphics/Rect");
4026cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    gRectClassInfo.left = env->GetFieldID(clazz, "left", "I");
403F{�i�ܼQfZy�.z����~���    gRectClassInfo.top = env->GetFieldID(clazz, "top", "I");
4046cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    gRectClassInfo.right = env->GetFieldID(clazz, "right", "I");
405A��p�<r�~��+d�M��qU�    gRectClassInfo.bottom = env->GetFieldID(clazz, "bottom", "I");
4066cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
4076cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy    return err;
4086cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy}
4096cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy
4106cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy};
4116cd229b7a352c48b750cd9fc92eae13eeacd593fClay Murphy