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