Loading core/jni/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -386,10 +386,12 @@ cc_library_static { local_include_dirs: [ "include", // NEEDED FOR ANDROID RUNTIME "android/graphics", "android/graphics/apex/include", ], export_include_dirs: [ ".", "android/graphics/apex/include", ], include_dirs: [ Loading Loading @@ -417,6 +419,8 @@ cc_library_static { target: { android: { srcs: [ // sources that depend on android only libraries "android/graphics/apex/android_canvas.cpp", "android_view_TextureLayer.cpp", "android_view_ThreadedRenderer.cpp", "android/graphics/BitmapRegionDecoder.cpp", Loading core/jni/android/graphics/apex/android_canvas.cpp 0 → 100644 +70 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "android/graphics/canvas.h" #include "GraphicsJNI.h" #include <hwui/Canvas.h> #include <utils/Color.h> #include <SkBitmap.h> using namespace android; static inline Canvas* toCanvas(ACanvas* aCanvas) { return reinterpret_cast<Canvas*>(aCanvas); } static inline ACanvas* toACanvas(Canvas* canvas) { return reinterpret_cast<ACanvas*>(canvas); } bool ACanvas_isSupportedPixelFormat(int32_t bufferFormat) { ANativeWindow_Buffer buffer { 0, 0, 0, bufferFormat, nullptr, {0} }; const SkColorType colorType = uirenderer::ANativeWindowToImageInfo(buffer, nullptr).colorType(); return kUnknown_SkColorType != colorType; } ACanvas* ACanvas_getNativeHandleFromJava(JNIEnv* env, jobject canvasObj) { return toACanvas(GraphicsJNI::getNativeCanvas(env, canvasObj)); } void ACanvas_setBuffer(ACanvas* canvas, const ANativeWindow_Buffer* buffer, int32_t /*android_dataspace_t*/ dataspace) { SkBitmap bitmap; if (buffer != nullptr && buffer->width > 0 && buffer->height > 0) { sk_sp<SkColorSpace> cs(uirenderer::DataSpaceToColorSpace((android_dataspace)dataspace)); SkImageInfo imageInfo = uirenderer::ANativeWindowToImageInfo(*buffer, cs); ssize_t rowBytes = buffer->stride * imageInfo.bytesPerPixel(); bitmap.setInfo(imageInfo, rowBytes); bitmap.setPixels(buffer->bits); } toCanvas(canvas)->setBitmap(bitmap); } void ACanvas_clipRect(ACanvas* canvas, const ARect& clipRect, bool /*doAA*/) { //TODO update Canvas to take antialias param toCanvas(canvas)->clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, SkClipOp::kIntersect); } void ACanvas_clipOutRect(ACanvas* canvas, const ARect& clipRect, bool /*doAA*/) { //TODO update Canvas to take antialias param toCanvas(canvas)->clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, SkClipOp::kDifference); } core/jni/android/graphics/apex/include/android/graphics/canvas.h 0 → 100644 +66 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_GRAPHICS_CANVAS_H #define ANDROID_GRAPHICS_CANVAS_H #include <android/native_window.h> #include <android/rect.h> #include <jni.h> __BEGIN_DECLS /** * Opaque handle for a native graphics canvas. */ typedef struct ACanvas ACanvas; // One of AHardwareBuffer_Format. bool ACanvas_isSupportedPixelFormat(int32_t bufferFormat); /** * Returns a native handle to a Java android.graphics.Canvas * * @param env * @param canvas * @return ACanvas* that is only valid for the life of the jobject. */ ACanvas* ACanvas_getNativeHandleFromJava(JNIEnv* env, jobject canvas); /** * Updates the canvas to render into the pixels in the provided buffer * * @param canvas * @param buffer The buffer that will provide the backing store for this canvas. The buffer must * remain valid until the this method is called again with either another active * buffer or nullptr. If nullptr is given the canvas will release the previous buffer * and set an empty backing store. * @param dataspace */ void ACanvas_setBuffer(ACanvas* canvas, const ANativeWindow_Buffer* buffer, int32_t /*android_dataspace_t*/ dataspace); /** * Clips operations on the canvas to the intersection of the current clip and the provided clipRect. */ void ACanvas_clipRect(ACanvas* canvas, const ARect& clipRect, bool doAntiAlias = false); /** * Clips operations on the canvas to the difference of the current clip and the provided clipRect. */ void ACanvas_clipOutRect(ACanvas* canvas, const ARect& clipRect, bool doAntiAlias = false); __END_DECLS #endif // ANDROID_GRAPHICS_CANVAS_H No newline at end of file core/jni/android_graphics_GraphicBuffer.cpp +18 −46 Original line number Diff line number Diff line Loading @@ -21,11 +21,6 @@ #include <inttypes.h> #include "android_os_Parcel.h" #include "android/graphics/GraphicsJNI.h" #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_graphics_GraphicBuffer.h> #include <binder/Parcel.h> #include <log/log.h> Loading @@ -33,10 +28,10 @@ #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <hwui/Bitmap.h> #include <SkCanvas.h> #include <SkBitmap.h> #include <android/native_window.h> #include <android/graphics/canvas.h> #include <android_runtime/android_graphics_GraphicBuffer.h> #include <private/android/AHardwareBufferHelpers.h> #include <private/gui/ComposerService.h> Loading Loading @@ -146,23 +141,8 @@ static void android_graphics_GraphicBuffer_destroy(JNIEnv* env, jobject clazz, // Canvas management // ---------------------------------------------------------------------------- static inline SkColorType convertPixelFormat(int32_t format) { switch (format) { case PIXEL_FORMAT_RGBA_8888: return kN32_SkColorType; case PIXEL_FORMAT_RGBX_8888: return kN32_SkColorType; case PIXEL_FORMAT_RGBA_FP16: return kRGBA_F16_SkColorType; case PIXEL_FORMAT_RGB_565: return kRGB_565_SkColorType; default: return kUnknown_SkColorType; } } static jboolean android_graphics_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, jlong wrapperHandle, jobject canvas, jobject dirtyRect) { jlong wrapperHandle, jobject canvasObj, jobject dirtyRect) { GraphicBufferWrapper* wrapper = reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle); Loading Loading @@ -191,24 +171,16 @@ static jboolean android_graphics_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, return JNI_FALSE; } ssize_t bytesCount = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat()); SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(buffer->getWidth(), buffer->getHeight(), convertPixelFormat(buffer->getPixelFormat()), kPremul_SkAlphaType), bytesCount); if (buffer->getWidth() > 0 && buffer->getHeight() > 0) { bitmap.setPixels(bits); } else { bitmap.setPixels(NULL); } ANativeWindow_Buffer nativeBuffer; nativeBuffer.width = buffer->getWidth(); nativeBuffer.height = buffer->getHeight(); nativeBuffer.stride = buffer->getStride(); nativeBuffer.format = AHardwareBuffer_convertFromPixelFormat(buffer->getPixelFormat()); nativeBuffer.bits = bits; Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas); nativeCanvas->setBitmap(bitmap); nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom, SkClipOp::kIntersect); ACanvas* canvas = ACanvas_getNativeHandleFromJava(env, canvasObj); ACanvas_setBuffer(canvas, &nativeBuffer, ADATASPACE_UNKNOWN); ACanvas_clipRect(canvas, {rect.left, rect.top, rect.right, rect.bottom}); if (dirtyRect) { INVOKEV(dirtyRect, gRectClassInfo.set, Loading @@ -219,13 +191,13 @@ static jboolean android_graphics_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, } static jboolean android_graphics_GraphicBuffer_unlockCanvasAndPost(JNIEnv* env, jobject, jlong wrapperHandle, jobject canvas) { jlong wrapperHandle, jobject canvasObj) { // release the buffer from the canvas ACanvas* canvas = ACanvas_getNativeHandleFromJava(env, canvasObj); ACanvas_setBuffer(canvas, nullptr, ADATASPACE_UNKNOWN); GraphicBufferWrapper* wrapper = reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle); Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas); nativeCanvas->setBitmap(SkBitmap()); if (wrapper) { status_t status = wrapper->get()->unlock(); return status == 0 ? JNI_TRUE : JNI_FALSE; Loading core/jni/android_view_Surface.cpp +13 −33 Original line number Diff line number Diff line Loading @@ -20,15 +20,16 @@ #include "jni.h" #include <nativehelper/JNIHelp.h> #include "android_os_Parcel.h" #include "android/graphics/GraphicsJNI.h" #include "core_jni_helpers.h" #include <android/graphics/canvas.h> #include <android_runtime/android_graphics_GraphicBuffer.h> #include <android_runtime/android_graphics_SurfaceTexture.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/Log.h> #include <private/android/AHardwareBufferHelpers.h> #include "android_os_Parcel.h" #include <binder/Parcel.h> #include <gui/Surface.h> Loading @@ -39,11 +40,6 @@ #include <ui/Rect.h> #include <ui/Region.h> #include <SkCanvas.h> #include <SkBitmap.h> #include <SkImage.h> #include <SkRegion.h> #include <utils/misc.h> #include <utils/Log.h> Loading Loading @@ -232,37 +228,21 @@ static jlong nativeLockCanvas(JNIEnv* env, jclass clazz, dirtyRectPtr = &dirtyRect; } ANativeWindow_Buffer outBuffer; status_t err = surface->lock(&outBuffer, dirtyRectPtr); ANativeWindow_Buffer buffer; status_t err = surface->lock(&buffer, dirtyRectPtr); if (err < 0) { const char* const exception = (err == NO_MEMORY) ? OutOfResourcesException : "java/lang/IllegalArgumentException"; OutOfResourcesException : IllegalArgumentException; jniThrowException(env, exception, NULL); return 0; } SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height, convertPixelFormat(outBuffer.format), outBuffer.format == PIXEL_FORMAT_RGBX_8888 ? kOpaque_SkAlphaType : kPremul_SkAlphaType); SkBitmap bitmap; ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format); bitmap.setInfo(info, bpr); if (outBuffer.width > 0 && outBuffer.height > 0) { bitmap.setPixels(outBuffer.bits); } else { // be safe with an empty bitmap. bitmap.setPixels(NULL); } Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj); nativeCanvas->setBitmap(bitmap); ACanvas* canvas = ACanvas_getNativeHandleFromJava(env, canvasObj); ACanvas_setBuffer(canvas, &buffer, static_cast<int32_t>(surface->getBuffersDataSpace())); if (dirtyRectPtr) { nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, SkClipOp::kIntersect); ACanvas_clipRect(canvas, {dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom}); } if (dirtyRectObj) { Loading @@ -288,8 +268,8 @@ static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, } // detach the canvas from the surface Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj); nativeCanvas->setBitmap(SkBitmap()); ACanvas* canvas = ACanvas_getNativeHandleFromJava(env, canvasObj); ACanvas_setBuffer(canvas, nullptr, ADATASPACE_UNKNOWN); // unlock surface status_t err = surface->unlockAndPost(); Loading Loading
core/jni/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -386,10 +386,12 @@ cc_library_static { local_include_dirs: [ "include", // NEEDED FOR ANDROID RUNTIME "android/graphics", "android/graphics/apex/include", ], export_include_dirs: [ ".", "android/graphics/apex/include", ], include_dirs: [ Loading Loading @@ -417,6 +419,8 @@ cc_library_static { target: { android: { srcs: [ // sources that depend on android only libraries "android/graphics/apex/android_canvas.cpp", "android_view_TextureLayer.cpp", "android_view_ThreadedRenderer.cpp", "android/graphics/BitmapRegionDecoder.cpp", Loading
core/jni/android/graphics/apex/android_canvas.cpp 0 → 100644 +70 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "android/graphics/canvas.h" #include "GraphicsJNI.h" #include <hwui/Canvas.h> #include <utils/Color.h> #include <SkBitmap.h> using namespace android; static inline Canvas* toCanvas(ACanvas* aCanvas) { return reinterpret_cast<Canvas*>(aCanvas); } static inline ACanvas* toACanvas(Canvas* canvas) { return reinterpret_cast<ACanvas*>(canvas); } bool ACanvas_isSupportedPixelFormat(int32_t bufferFormat) { ANativeWindow_Buffer buffer { 0, 0, 0, bufferFormat, nullptr, {0} }; const SkColorType colorType = uirenderer::ANativeWindowToImageInfo(buffer, nullptr).colorType(); return kUnknown_SkColorType != colorType; } ACanvas* ACanvas_getNativeHandleFromJava(JNIEnv* env, jobject canvasObj) { return toACanvas(GraphicsJNI::getNativeCanvas(env, canvasObj)); } void ACanvas_setBuffer(ACanvas* canvas, const ANativeWindow_Buffer* buffer, int32_t /*android_dataspace_t*/ dataspace) { SkBitmap bitmap; if (buffer != nullptr && buffer->width > 0 && buffer->height > 0) { sk_sp<SkColorSpace> cs(uirenderer::DataSpaceToColorSpace((android_dataspace)dataspace)); SkImageInfo imageInfo = uirenderer::ANativeWindowToImageInfo(*buffer, cs); ssize_t rowBytes = buffer->stride * imageInfo.bytesPerPixel(); bitmap.setInfo(imageInfo, rowBytes); bitmap.setPixels(buffer->bits); } toCanvas(canvas)->setBitmap(bitmap); } void ACanvas_clipRect(ACanvas* canvas, const ARect& clipRect, bool /*doAA*/) { //TODO update Canvas to take antialias param toCanvas(canvas)->clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, SkClipOp::kIntersect); } void ACanvas_clipOutRect(ACanvas* canvas, const ARect& clipRect, bool /*doAA*/) { //TODO update Canvas to take antialias param toCanvas(canvas)->clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, SkClipOp::kDifference); }
core/jni/android/graphics/apex/include/android/graphics/canvas.h 0 → 100644 +66 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_GRAPHICS_CANVAS_H #define ANDROID_GRAPHICS_CANVAS_H #include <android/native_window.h> #include <android/rect.h> #include <jni.h> __BEGIN_DECLS /** * Opaque handle for a native graphics canvas. */ typedef struct ACanvas ACanvas; // One of AHardwareBuffer_Format. bool ACanvas_isSupportedPixelFormat(int32_t bufferFormat); /** * Returns a native handle to a Java android.graphics.Canvas * * @param env * @param canvas * @return ACanvas* that is only valid for the life of the jobject. */ ACanvas* ACanvas_getNativeHandleFromJava(JNIEnv* env, jobject canvas); /** * Updates the canvas to render into the pixels in the provided buffer * * @param canvas * @param buffer The buffer that will provide the backing store for this canvas. The buffer must * remain valid until the this method is called again with either another active * buffer or nullptr. If nullptr is given the canvas will release the previous buffer * and set an empty backing store. * @param dataspace */ void ACanvas_setBuffer(ACanvas* canvas, const ANativeWindow_Buffer* buffer, int32_t /*android_dataspace_t*/ dataspace); /** * Clips operations on the canvas to the intersection of the current clip and the provided clipRect. */ void ACanvas_clipRect(ACanvas* canvas, const ARect& clipRect, bool doAntiAlias = false); /** * Clips operations on the canvas to the difference of the current clip and the provided clipRect. */ void ACanvas_clipOutRect(ACanvas* canvas, const ARect& clipRect, bool doAntiAlias = false); __END_DECLS #endif // ANDROID_GRAPHICS_CANVAS_H No newline at end of file
core/jni/android_graphics_GraphicBuffer.cpp +18 −46 Original line number Diff line number Diff line Loading @@ -21,11 +21,6 @@ #include <inttypes.h> #include "android_os_Parcel.h" #include "android/graphics/GraphicsJNI.h" #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_graphics_GraphicBuffer.h> #include <binder/Parcel.h> #include <log/log.h> Loading @@ -33,10 +28,10 @@ #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <hwui/Bitmap.h> #include <SkCanvas.h> #include <SkBitmap.h> #include <android/native_window.h> #include <android/graphics/canvas.h> #include <android_runtime/android_graphics_GraphicBuffer.h> #include <private/android/AHardwareBufferHelpers.h> #include <private/gui/ComposerService.h> Loading Loading @@ -146,23 +141,8 @@ static void android_graphics_GraphicBuffer_destroy(JNIEnv* env, jobject clazz, // Canvas management // ---------------------------------------------------------------------------- static inline SkColorType convertPixelFormat(int32_t format) { switch (format) { case PIXEL_FORMAT_RGBA_8888: return kN32_SkColorType; case PIXEL_FORMAT_RGBX_8888: return kN32_SkColorType; case PIXEL_FORMAT_RGBA_FP16: return kRGBA_F16_SkColorType; case PIXEL_FORMAT_RGB_565: return kRGB_565_SkColorType; default: return kUnknown_SkColorType; } } static jboolean android_graphics_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, jlong wrapperHandle, jobject canvas, jobject dirtyRect) { jlong wrapperHandle, jobject canvasObj, jobject dirtyRect) { GraphicBufferWrapper* wrapper = reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle); Loading Loading @@ -191,24 +171,16 @@ static jboolean android_graphics_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, return JNI_FALSE; } ssize_t bytesCount = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat()); SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(buffer->getWidth(), buffer->getHeight(), convertPixelFormat(buffer->getPixelFormat()), kPremul_SkAlphaType), bytesCount); if (buffer->getWidth() > 0 && buffer->getHeight() > 0) { bitmap.setPixels(bits); } else { bitmap.setPixels(NULL); } ANativeWindow_Buffer nativeBuffer; nativeBuffer.width = buffer->getWidth(); nativeBuffer.height = buffer->getHeight(); nativeBuffer.stride = buffer->getStride(); nativeBuffer.format = AHardwareBuffer_convertFromPixelFormat(buffer->getPixelFormat()); nativeBuffer.bits = bits; Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas); nativeCanvas->setBitmap(bitmap); nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom, SkClipOp::kIntersect); ACanvas* canvas = ACanvas_getNativeHandleFromJava(env, canvasObj); ACanvas_setBuffer(canvas, &nativeBuffer, ADATASPACE_UNKNOWN); ACanvas_clipRect(canvas, {rect.left, rect.top, rect.right, rect.bottom}); if (dirtyRect) { INVOKEV(dirtyRect, gRectClassInfo.set, Loading @@ -219,13 +191,13 @@ static jboolean android_graphics_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, } static jboolean android_graphics_GraphicBuffer_unlockCanvasAndPost(JNIEnv* env, jobject, jlong wrapperHandle, jobject canvas) { jlong wrapperHandle, jobject canvasObj) { // release the buffer from the canvas ACanvas* canvas = ACanvas_getNativeHandleFromJava(env, canvasObj); ACanvas_setBuffer(canvas, nullptr, ADATASPACE_UNKNOWN); GraphicBufferWrapper* wrapper = reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle); Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas); nativeCanvas->setBitmap(SkBitmap()); if (wrapper) { status_t status = wrapper->get()->unlock(); return status == 0 ? JNI_TRUE : JNI_FALSE; Loading
core/jni/android_view_Surface.cpp +13 −33 Original line number Diff line number Diff line Loading @@ -20,15 +20,16 @@ #include "jni.h" #include <nativehelper/JNIHelp.h> #include "android_os_Parcel.h" #include "android/graphics/GraphicsJNI.h" #include "core_jni_helpers.h" #include <android/graphics/canvas.h> #include <android_runtime/android_graphics_GraphicBuffer.h> #include <android_runtime/android_graphics_SurfaceTexture.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/Log.h> #include <private/android/AHardwareBufferHelpers.h> #include "android_os_Parcel.h" #include <binder/Parcel.h> #include <gui/Surface.h> Loading @@ -39,11 +40,6 @@ #include <ui/Rect.h> #include <ui/Region.h> #include <SkCanvas.h> #include <SkBitmap.h> #include <SkImage.h> #include <SkRegion.h> #include <utils/misc.h> #include <utils/Log.h> Loading Loading @@ -232,37 +228,21 @@ static jlong nativeLockCanvas(JNIEnv* env, jclass clazz, dirtyRectPtr = &dirtyRect; } ANativeWindow_Buffer outBuffer; status_t err = surface->lock(&outBuffer, dirtyRectPtr); ANativeWindow_Buffer buffer; status_t err = surface->lock(&buffer, dirtyRectPtr); if (err < 0) { const char* const exception = (err == NO_MEMORY) ? OutOfResourcesException : "java/lang/IllegalArgumentException"; OutOfResourcesException : IllegalArgumentException; jniThrowException(env, exception, NULL); return 0; } SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height, convertPixelFormat(outBuffer.format), outBuffer.format == PIXEL_FORMAT_RGBX_8888 ? kOpaque_SkAlphaType : kPremul_SkAlphaType); SkBitmap bitmap; ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format); bitmap.setInfo(info, bpr); if (outBuffer.width > 0 && outBuffer.height > 0) { bitmap.setPixels(outBuffer.bits); } else { // be safe with an empty bitmap. bitmap.setPixels(NULL); } Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj); nativeCanvas->setBitmap(bitmap); ACanvas* canvas = ACanvas_getNativeHandleFromJava(env, canvasObj); ACanvas_setBuffer(canvas, &buffer, static_cast<int32_t>(surface->getBuffersDataSpace())); if (dirtyRectPtr) { nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, SkClipOp::kIntersect); ACanvas_clipRect(canvas, {dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom}); } if (dirtyRectObj) { Loading @@ -288,8 +268,8 @@ static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, } // detach the canvas from the surface Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj); nativeCanvas->setBitmap(SkBitmap()); ACanvas* canvas = ACanvas_getNativeHandleFromJava(env, canvasObj); ACanvas_setBuffer(canvas, nullptr, ADATASPACE_UNKNOWN); // unlock surface status_t err = surface->unlockAndPost(); Loading