13b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/* 23b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Copyright (C) 2013 The Android Open Source Project 33b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * 43b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 53b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * you may not use this file except in compliance with the License. 63b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * You may obtain a copy of the License at 73b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * 83b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 93b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * 103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Unless required by applicable law or agreed to in writing, software 113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * See the License for the specific language governing permissions and 143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * limitations under the License. 153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */ 163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define LOG_TAG "GraphicBuffer" 183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "jni.h" 203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "JNIHelp.h" 213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "android_os_Parcel.h" 233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "android_view_GraphicBuffer.h" 243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <android_runtime/AndroidRuntime.h> 263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <binder/Parcel.h> 283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <ui/GraphicBuffer.h> 303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <ui/PixelFormat.h> 313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <gui/IGraphicBufferAlloc.h> 333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <gui/ISurfaceComposer.h> 343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <SkCanvas.h> 363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <SkBitmap.h> 373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <private/gui/ComposerService.h> 393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace android { 413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Defines 443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Debug 473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define DEBUG_GRAPHIC_BUFFER 0 483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Debug 503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#if DEBUG_GRAPHIC_BUFFER 513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy #define GB_LOGD(...) ALOGD(__VA_ARGS__) 523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy #define GB_LOGW(...) ALOGW(__VA_ARGS__) 533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#else 543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy #define GB_LOGD(...) 553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy #define GB_LOGW(...) 563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#endif 573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define LOCK_CANVAS_USAGE GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_OFTEN 593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// JNI Helpers 623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic struct { 653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID mNativeObject; 663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} gGraphicBufferClassInfo; 673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic struct { 693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jmethodID set; 703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID left; 713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID top; 723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID right; 733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID bottom; 743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} gRectClassInfo; 753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic struct { 773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID mFinalizer; 783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID mNativeCanvas; 793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID mSurfaceFormat; 803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} gCanvasClassInfo; 813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic struct { 833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID mNativeCanvas; 843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} gCanvasFinalizerClassInfo; 853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define GET_INT(object, field) \ 873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy env->GetIntField(object, field) 883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define SET_INT(object, field, value) \ 903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy env->SetIntField(object, field, value) 913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define INVOKEV(object, method, ...) \ 933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy env->CallVoidMethod(object, method, __VA_ARGS__) 943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Types 973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 983b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyclass GraphicBufferWrapper { 1003b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guypublic: 1013b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GraphicBufferWrapper(const sp<GraphicBuffer>& buffer): buffer(buffer) { 1023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1033b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1043b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer; 1053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; 1063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// GraphicBuffer lifecycle 1093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic GraphicBufferWrapper* android_view_GraphiceBuffer_create(JNIEnv* env, jobject clazz, 1123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jint width, jint height, jint format, jint usage) { 1133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 1153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc()); 1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (alloc == NULL) { 1173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GB_LOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()"); 1183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return NULL; 1193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy status_t error; 1223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, usage, &error)); 1233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (buffer == NULL) { 1243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GB_LOGW("createGraphicBuffer() failed in GraphicBuffer.create()"); 1253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return NULL; 1263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return new GraphicBufferWrapper(buffer); 1293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic void android_view_GraphiceBuffer_destroy(JNIEnv* env, jobject clazz, 1323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GraphicBufferWrapper* wrapper) { 1333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy delete wrapper; 1343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Canvas management 1383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) { 1413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer); 1423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>( 1433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas)); 1443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas, (int) newCanvas); 1453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SET_INT(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int) newCanvas); 1463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkSafeUnref(previousCanvas); 1473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic inline SkBitmap::Config convertPixelFormat(int32_t format) { 1503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy switch (format) { 1513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy case PIXEL_FORMAT_RGBA_8888: 1523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return SkBitmap::kARGB_8888_Config; 1533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy case PIXEL_FORMAT_RGBX_8888: 1543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return SkBitmap::kARGB_8888_Config; 1553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy case PIXEL_FORMAT_RGB_565: 1563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return SkBitmap::kRGB_565_Config; 1573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy default: 1583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return SkBitmap::kNo_Config; 1593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic jboolean android_view_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, 1633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GraphicBufferWrapper* wrapper, jobject canvas, jobject dirtyRect) { 1643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (!wrapper) { 1663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return false; 1673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer(wrapper->buffer); 1703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy Rect rect; 1723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (dirtyRect) { 1733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.left = GET_INT(dirtyRect, gRectClassInfo.left); 1743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.top = GET_INT(dirtyRect, gRectClassInfo.top); 1753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.right = GET_INT(dirtyRect, gRectClassInfo.right); 1763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.bottom = GET_INT(dirtyRect, gRectClassInfo.bottom); 1773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } else { 1783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.set(Rect(buffer->getWidth(), buffer->getHeight())); 1793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy void* bits = NULL; 1823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy status_t status = buffer->lock(LOCK_CANVAS_USAGE, rect, &bits); 1833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (status) return false; 1853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (!bits) { 1863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy buffer->unlock(); 1873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return false; 1883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy ssize_t bytesCount = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat()); 1913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkBitmap bitmap; 1933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy bitmap.setConfig(convertPixelFormat(buffer->getPixelFormat()), 1943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy buffer->getWidth(), buffer->getHeight(), bytesCount); 1953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (buffer->getWidth() > 0 && buffer->getHeight() > 0) { 1973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy bitmap.setPixels(bits); 1983b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } else { 1993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy bitmap.setPixels(NULL); 2003b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2013b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer->getPixelFormat()); 2033b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2043b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap)); 2053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy swapCanvasPtr(env, canvas, nativeCanvas); 2063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkRect clipRect; 2083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy clipRect.set(rect.left, rect.top, rect.right, rect.bottom); 2093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy nativeCanvas->clipRect(clipRect); 2103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (dirtyRect) { 2123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy INVOKEV(dirtyRect, gRectClassInfo.set, 2133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy int(rect.left), int(rect.top), int(rect.right), int(rect.bottom)); 2143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return true; 2173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic jboolean android_view_GraphicBuffer_unlockCanvasAndPost(JNIEnv* env, jobject, 2203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GraphicBufferWrapper* wrapper, jobject canvas) { 2213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkCanvas* nativeCanvas = SkNEW(SkCanvas); 2233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy swapCanvasPtr(env, canvas, nativeCanvas); 2243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (wrapper) { 2263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy status_t status = wrapper->buffer->unlock(); 2273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return status == 0; 2283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return false; 2313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Serialization 2353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic void android_view_GraphiceBuffer_write(JNIEnv* env, jobject clazz, 2383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GraphicBufferWrapper* wrapper, jobject dest) { 2393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy Parcel* parcel = parcelForJavaObject(env, dest); 2403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (parcel) { 2413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy parcel->write(*wrapper->buffer); 2423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic GraphicBufferWrapper* android_view_GraphiceBuffer_read(JNIEnv* env, jobject clazz, 2463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jobject in) { 2473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy Parcel* parcel = parcelForJavaObject(env, in); 2493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (parcel) { 2503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer = new GraphicBuffer(); 2513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy parcel->read(*buffer); 2523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return new GraphicBufferWrapper(buffer); 2533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return NULL; 2563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// External helpers 2603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guysp<GraphicBuffer> graphicBufferForJavaObject(JNIEnv* env, jobject obj) { 2633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (obj) { 2643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jint nativeObject = env->GetIntField(obj, gGraphicBufferClassInfo.mNativeObject); 2653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GraphicBufferWrapper* wrapper = (GraphicBufferWrapper*) nativeObject; 2663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (wrapper != NULL) { 2673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer(wrapper->buffer); 2683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return buffer; 2693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return NULL; 2723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// JNI Glue 2763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define FIND_CLASS(var, className) \ 2793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy var = env->FindClass(className); \ 2803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy LOG_FATAL_IF(! var, "Unable to find class " className); 2813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 2833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 2843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy LOG_FATAL_IF(! var, "Unable to find field " fieldName); 2853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 2873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 2883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy LOG_FATAL_IF(!var, "Unable to find method " methodName); 2893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyconst char* const kClassPathName = "android/view/GraphicBuffer"; 2913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic JNINativeMethod gMethods[] = { 2933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy { "nCreateGraphicBuffer", "(IIII)I", (void*) android_view_GraphiceBuffer_create }, 2943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy { "nDestroyGraphicBuffer", "(I)V", (void*) android_view_GraphiceBuffer_destroy }, 2953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy { "nWriteGraphicBufferToParcel", "(ILandroid/os/Parcel;)V", 2973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy (void*) android_view_GraphiceBuffer_write }, 2983b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy { "nReadGraphicBufferFromParcel", "(Landroid/os/Parcel;)I", 2993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy (void*) android_view_GraphiceBuffer_read }, 3003b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3013b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)Z", 3023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy (void*) android_view_GraphicBuffer_lockCanvas }, 3033b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy { "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)Z", 3043b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy (void*) android_view_GraphicBuffer_unlockCanvasAndPost }, 3053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; 3063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyint register_android_view_GraphicBuffer(JNIEnv* env) { 3083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jclass clazz; 3093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy FIND_CLASS(clazz, "android/view/GraphicBuffer"); 3103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gGraphicBufferClassInfo.mNativeObject, clazz, "mNativeObject", "I"); 3113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy FIND_CLASS(clazz, "android/graphics/Rect"); 3133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V"); 3143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I"); 3153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I"); 3163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I"); 3173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I"); 3183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy FIND_CLASS(clazz, "android/graphics/Canvas"); 3203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", 3213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy "Landroid/graphics/Canvas$CanvasFinalizer;"); 3223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I"); 3233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I"); 3243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer"); 3263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I"); 3273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 3293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 3303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; 332