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" 245c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita#include "android/graphics/GraphicsJNI.h" 253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <android_runtime/AndroidRuntime.h> 273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <binder/Parcel.h> 293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <ui/GraphicBuffer.h> 313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <ui/PixelFormat.h> 323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <gui/IGraphicBufferAlloc.h> 343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <gui/ISurfaceComposer.h> 353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <SkCanvas.h> 373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <SkBitmap.h> 383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <private/gui/ComposerService.h> 403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace android { 423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Defines 453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Debug 483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define DEBUG_GRAPHIC_BUFFER 0 493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Debug 513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#if DEBUG_GRAPHIC_BUFFER 523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy #define GB_LOGD(...) ALOGD(__VA_ARGS__) 533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy #define GB_LOGW(...) ALOGW(__VA_ARGS__) 543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#else 553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy #define GB_LOGD(...) 563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy #define GB_LOGW(...) 573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#endif 583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define LOCK_CANVAS_USAGE GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_OFTEN 603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// JNI Helpers 633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic struct { 663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID mNativeObject; 673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} gGraphicBufferClassInfo; 683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic struct { 703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jmethodID set; 713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID left; 723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID top; 733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID right; 743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID bottom; 753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} gRectClassInfo; 763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic struct { 783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jfieldID mSurfaceFormat; 795c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita jmethodID setNativeBitmap; 803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} gCanvasClassInfo; 813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define GET_INT(object, field) \ 833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy env->GetIntField(object, field) 843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define SET_INT(object, field, value) \ 863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy env->SetIntField(object, field, value) 873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 8836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat#define GET_LONG(object, field) \ 8936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat env->GetLongField(object, field) 9036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat 9136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat#define SET_LONG(object, field, value) \ 9236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat env->SetLongField(object, field, value) 9336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat 943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define INVOKEV(object, method, ...) \ 953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy env->CallVoidMethod(object, method, __VA_ARGS__) 963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 983b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Types 993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1003b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1013b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyclass GraphicBufferWrapper { 1023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guypublic: 1033b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GraphicBufferWrapper(const sp<GraphicBuffer>& buffer): buffer(buffer) { 1043b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer; 1073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; 1083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// GraphicBuffer lifecycle 1113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 11336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jlong android_view_GraphiceBuffer_create(JNIEnv* env, jobject clazz, 1143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jint width, jint height, jint format, jint usage) { 1153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 1173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc()); 1183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (alloc == NULL) { 1193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GB_LOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()"); 1203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return NULL; 1213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy status_t error; 1243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, usage, &error)); 1253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (buffer == NULL) { 1263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GB_LOGW("createGraphicBuffer() failed in GraphicBuffer.create()"); 1273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return NULL; 1283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 13036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat GraphicBufferWrapper* wrapper = new GraphicBufferWrapper(buffer); 13136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(wrapper); 1323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic void android_view_GraphiceBuffer_destroy(JNIEnv* env, jobject clazz, 13536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jlong wrapperHandle) { 13636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat GraphicBufferWrapper* wrapper = 13736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle); 1383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy delete wrapper; 1393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Canvas management 1433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 1443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 145b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reedstatic inline SkColorType convertPixelFormat(int32_t format) { 1463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy switch (format) { 1473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy case PIXEL_FORMAT_RGBA_8888: 148b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed return kN32_SkColorType; 1493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy case PIXEL_FORMAT_RGBX_8888: 150b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed return kN32_SkColorType; 1513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy case PIXEL_FORMAT_RGB_565: 152b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed return kRGB_565_SkColorType; 1533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy default: 154b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed return kUnknown_SkColorType; 1553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic jboolean android_view_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, 15936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jlong wrapperHandle, jobject canvas, jobject dirtyRect) { 1603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 16136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat GraphicBufferWrapper* wrapper = 16236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle); 1633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (!wrapper) { 16436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return JNI_FALSE; 1653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer(wrapper->buffer); 1683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy Rect rect; 1703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (dirtyRect) { 1713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.left = GET_INT(dirtyRect, gRectClassInfo.left); 1723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.top = GET_INT(dirtyRect, gRectClassInfo.top); 1733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.right = GET_INT(dirtyRect, gRectClassInfo.right); 1743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.bottom = GET_INT(dirtyRect, gRectClassInfo.bottom); 1753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } else { 1763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy rect.set(Rect(buffer->getWidth(), buffer->getHeight())); 1773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy void* bits = NULL; 1803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy status_t status = buffer->lock(LOCK_CANVAS_USAGE, rect, &bits); 1813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 18236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat if (status) return JNI_FALSE; 1833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (!bits) { 1843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy buffer->unlock(); 18536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return JNI_FALSE; 1863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy ssize_t bytesCount = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat()); 1893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkBitmap bitmap; 191b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed bitmap.setInfo(SkImageInfo::Make(buffer->getWidth(), buffer->getHeight(), 192b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed convertPixelFormat(buffer->getPixelFormat()), 193b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kPremul_SkAlphaType), 194b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed 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()); 2035c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita INVOKEV(canvas, gCanvasClassInfo.setNativeBitmap, reinterpret_cast<jlong>(&bitmap)); 2043b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkRect clipRect; 2063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy clipRect.set(rect.left, rect.top, rect.right, rect.bottom); 2075c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita SkCanvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas); 2083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy nativeCanvas->clipRect(clipRect); 2093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (dirtyRect) { 2113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy INVOKEV(dirtyRect, gRectClassInfo.set, 2123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy int(rect.left), int(rect.top), int(rect.right), int(rect.bottom)); 2133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 21536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return JNI_TRUE; 2163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic jboolean android_view_GraphicBuffer_unlockCanvasAndPost(JNIEnv* env, jobject, 21936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jlong wrapperHandle, jobject canvas) { 2203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 22136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat GraphicBufferWrapper* wrapper = 22236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle); 2235c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita INVOKEV(canvas, gCanvasClassInfo.setNativeBitmap, (jlong)0); 2243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (wrapper) { 2263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy status_t status = wrapper->buffer->unlock(); 22736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return status == 0 ? JNI_TRUE : JNI_FALSE; 2283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 23036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return JNI_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, 23836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jlong wrapperHandle, jobject dest) { 23936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat GraphicBufferWrapper* wrapper = 24036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle); 2413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy Parcel* parcel = parcelForJavaObject(env, dest); 2423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (parcel) { 2433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy parcel->write(*wrapper->buffer); 2443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 24736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jlong android_view_GraphiceBuffer_read(JNIEnv* env, jobject clazz, 2483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jobject in) { 2493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy Parcel* parcel = parcelForJavaObject(env, in); 2513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (parcel) { 2523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer = new GraphicBuffer(); 2533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy parcel->read(*buffer); 25436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return reinterpret_cast<jlong>(new GraphicBufferWrapper(buffer)); 2553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return NULL; 2583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// External helpers 2623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guysp<GraphicBuffer> graphicBufferForJavaObject(JNIEnv* env, jobject obj) { 2653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (obj) { 26636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat jlong nativeObject = env->GetLongField(obj, gGraphicBufferClassInfo.mNativeObject); 2673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GraphicBufferWrapper* wrapper = (GraphicBufferWrapper*) nativeObject; 2683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (wrapper != NULL) { 2693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy sp<GraphicBuffer> buffer(wrapper->buffer); 2703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return buffer; 2713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 2733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return NULL; 2743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 2753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// JNI Glue 2783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// ---------------------------------------------------------------------------- 2793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define FIND_CLASS(var, className) \ 2813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy var = env->FindClass(className); \ 2823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy LOG_FATAL_IF(! var, "Unable to find class " className); 2833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 2853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 2863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy LOG_FATAL_IF(! var, "Unable to find field " fieldName); 2873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 2893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 2903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy LOG_FATAL_IF(!var, "Unable to find method " methodName); 2913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyconst char* const kClassPathName = "android/view/GraphicBuffer"; 2933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guystatic JNINativeMethod gMethods[] = { 29536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat { "nCreateGraphicBuffer", "(IIII)J", (void*) android_view_GraphiceBuffer_create }, 29636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat { "nDestroyGraphicBuffer", "(J)V", (void*) android_view_GraphiceBuffer_destroy }, 2973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 29836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat { "nWriteGraphicBufferToParcel", "(JLandroid/os/Parcel;)V", 2993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy (void*) android_view_GraphiceBuffer_write }, 30036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat { "nReadGraphicBufferFromParcel", "(Landroid/os/Parcel;)J", 3013b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy (void*) android_view_GraphiceBuffer_read }, 3023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 30336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat { "nLockCanvas", "(JLandroid/graphics/Canvas;Landroid/graphics/Rect;)Z", 3043b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy (void*) android_view_GraphicBuffer_lockCanvas }, 30536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat { "nUnlockCanvasAndPost", "(JLandroid/graphics/Canvas;)Z", 3063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy (void*) android_view_GraphicBuffer_unlockCanvasAndPost }, 3073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; 3083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyint register_android_view_GraphicBuffer(JNIEnv* env) { 3103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy jclass clazz; 3113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy FIND_CLASS(clazz, "android/view/GraphicBuffer"); 31236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat GET_FIELD_ID(gGraphicBufferClassInfo.mNativeObject, clazz, "mNativeObject", "J"); 3133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy FIND_CLASS(clazz, "android/graphics/Rect"); 3153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V"); 3163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I"); 3173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I"); 3183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I"); 3193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I"); 3203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy FIND_CLASS(clazz, "android/graphics/Canvas"); 3223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I"); 3235c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita GET_METHOD_ID(gCanvasClassInfo.setNativeBitmap, clazz, "setNativeBitmap", "(J)V"); 3243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 3263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 3273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; 329