| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/android/java_bitmap.h" | 5 #include "ui/gfx/android/java_bitmap.h" |
| 6 | 6 |
| 7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
| 8 | 8 |
| 9 #include "base/android/jni_android.h" | |
| 10 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "jni/BitmapHelper_jni.h" |
| 11 #include "third_party/skia/include/core/SkBitmap.h" | 11 #include "third_party/skia/include/core/SkBitmap.h" |
| 12 #include "ui/gfx/size.h" | 12 #include "ui/gfx/size.h" |
| 13 | 13 |
| 14 using base::android::AttachCurrentThread; | 14 using base::android::AttachCurrentThread; |
| 15 using base::android::GetClass; | |
| 16 using base::android::GetMethodID; | |
| 17 using base::android::GetStaticFieldID; | |
| 18 using base::android::GetStaticMethodID; | |
| 19 using base::android::ScopedJavaLocalRef; | |
| 20 | |
| 21 namespace { | |
| 22 static jclass g_AndroidBitmap_clazz = NULL; | |
| 23 static jmethodID g_AndroidBitmap_createBitmap_method = NULL; | |
| 24 static jobject g_BitmapConfig_ARGB8888 = NULL; | |
| 25 } // anonymous namespace | |
| 26 | 15 |
| 27 namespace gfx { | 16 namespace gfx { |
| 28 | 17 |
| 29 JavaBitmap::JavaBitmap(jobject bitmap) | 18 JavaBitmap::JavaBitmap(jobject bitmap) |
| 30 : bitmap_(bitmap), | 19 : bitmap_(bitmap), |
| 31 pixels_(NULL) { | 20 pixels_(NULL) { |
| 32 int err = AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_, &pixels_); | 21 int err = AndroidBitmap_lockPixels(AttachCurrentThread(), bitmap_, &pixels_); |
| 33 DCHECK(!err); | 22 DCHECK(!err); |
| 34 DCHECK(pixels_); | 23 DCHECK(pixels_); |
| 24 |
| 25 AndroidBitmapInfo info; |
| 26 err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); |
| 27 DCHECK(!err); |
| 28 size_ = gfx::Size(info.width, info.height); |
| 29 format_ = info.format; |
| 30 stride_ = info.stride; |
| 35 } | 31 } |
| 36 | 32 |
| 37 JavaBitmap::~JavaBitmap() { | 33 JavaBitmap::~JavaBitmap() { |
| 38 int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_); | 34 int err = AndroidBitmap_unlockPixels(AttachCurrentThread(), bitmap_); |
| 39 DCHECK(!err); | 35 DCHECK(!err); |
| 40 } | 36 } |
| 41 | 37 |
| 42 gfx::Size JavaBitmap::Size() const { | |
| 43 AndroidBitmapInfo info; | |
| 44 int err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); | |
| 45 DCHECK(!err); | |
| 46 return gfx::Size(info.width, info.height); | |
| 47 } | |
| 48 | |
| 49 int JavaBitmap::Format() const { | |
| 50 AndroidBitmapInfo info; | |
| 51 int err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); | |
| 52 DCHECK(!err); | |
| 53 return info.format; | |
| 54 } | |
| 55 | |
| 56 uint32_t JavaBitmap::Stride() const { | |
| 57 AndroidBitmapInfo info; | |
| 58 int err = AndroidBitmap_getInfo(AttachCurrentThread(), bitmap_, &info); | |
| 59 DCHECK(!err); | |
| 60 return info.stride; | |
| 61 } | |
| 62 | |
| 63 void RegisterBitmapAndroid(JNIEnv* env) { | 38 void RegisterBitmapAndroid(JNIEnv* env) { |
| 64 g_AndroidBitmap_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( | 39 ui::RegisterNativesImpl(env); |
| 65 base::android::GetUnscopedClass(env, "android/graphics/Bitmap"))); | |
| 66 ScopedJavaLocalRef<jclass> bitmapConfig_clazz = base::android::GetClass( | |
| 67 env, "android/graphics/Bitmap$Config"); | |
| 68 g_AndroidBitmap_createBitmap_method = GetStaticMethodID(env, | |
| 69 g_AndroidBitmap_clazz, "createBitmap", | |
| 70 "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;"); | |
| 71 jfieldID argb_8888_id = GetStaticFieldID(env, bitmapConfig_clazz, "ARGB_8888", | |
| 72 "Landroid/graphics/Bitmap$Config;"); | |
| 73 g_BitmapConfig_ARGB8888 = reinterpret_cast<jobject>(env->NewGlobalRef( | |
| 74 env->GetStaticObjectField(bitmapConfig_clazz.obj(), argb_8888_id))); | |
| 75 } | 40 } |
| 76 | 41 |
| 77 ScopedJavaLocalRef<jobject> CreateJavaBitmap(const gfx::Size& size) { | 42 ScopedJavaLocalRef<jobject> CreateJavaBitmap(const gfx::Size& size) { |
| 78 DCHECK(g_AndroidBitmap_clazz); | 43 return ui::Java_BitmapHelper_createBitmap(AttachCurrentThread(), |
| 79 JNIEnv* env = AttachCurrentThread(); | 44 size.width(), size.height()); |
| 80 jobject bitmap_object = env->CallStaticObjectMethod(g_AndroidBitmap_clazz, | |
| 81 g_AndroidBitmap_createBitmap_method, size.width(), size.height(), | |
| 82 g_BitmapConfig_ARGB8888); | |
| 83 return ScopedJavaLocalRef<jobject>(env, bitmap_object); | |
| 84 } | 45 } |
| 85 | 46 |
| 86 ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) { | 47 ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) { |
| 87 DCHECK(skbitmap); | 48 DCHECK(skbitmap); |
| 88 DCHECK_EQ(skbitmap->bytesPerPixel(), 4); | 49 DCHECK_EQ(skbitmap->bytesPerPixel(), 4); |
| 89 | 50 |
| 90 ScopedJavaLocalRef<jobject> jbitmap = | 51 ScopedJavaLocalRef<jobject> jbitmap = |
| 91 CreateJavaBitmap(gfx::Size(skbitmap->width(), skbitmap->height())); | 52 CreateJavaBitmap(gfx::Size(skbitmap->width(), skbitmap->height())); |
| 92 SkAutoLockPixels src_lock(*skbitmap); | 53 SkAutoLockPixels src_lock(*skbitmap); |
| 93 JavaBitmap dst_lock(jbitmap.obj()); | 54 JavaBitmap dst_lock(jbitmap.obj()); |
| 94 void* src_pixels = skbitmap->getPixels(); | 55 void* src_pixels = skbitmap->getPixels(); |
| 95 void* dst_pixels = dst_lock.pixels(); | 56 void* dst_pixels = dst_lock.pixels(); |
| 96 memcpy(dst_pixels, src_pixels, skbitmap->getSize()); | 57 memcpy(dst_pixels, src_pixels, skbitmap->getSize()); |
| 97 | 58 |
| 98 return jbitmap; | 59 return jbitmap; |
| 99 } | 60 } |
| 100 | 61 |
| 62 static ScopedJavaLocalRef<jobject> CreateJavaBitmapFromResource( |
| 63 const char* name) { |
| 64 JNIEnv* env = AttachCurrentThread(); |
| 65 ScopedJavaLocalRef<jstring> jname(env, env->NewStringUTF(name)); |
| 66 return ui::Java_BitmapHelper_decodeDrawableResource(env, jname.obj()); |
| 67 } |
| 68 |
| 69 static SkBitmap ConvertToSkBitmap(ScopedJavaLocalRef<jobject> jbitmap) { |
| 70 JavaBitmap src_lock(jbitmap.obj()); |
| 71 DCHECK_EQ(src_lock.format(), ANDROID_BITMAP_FORMAT_RGBA_8888); |
| 72 |
| 73 gfx::Size src_size = src_lock.size(); |
| 74 |
| 75 SkBitmap skbitmap; |
| 76 skbitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| 77 src_size.width(), src_size.height(), src_lock.stride()); |
| 78 skbitmap.allocPixels(); |
| 79 SkAutoLockPixels dst_lock(skbitmap); |
| 80 |
| 81 void* src_pixels = src_lock.pixels(); |
| 82 void* dst_pixels = skbitmap.getPixels(); |
| 83 |
| 84 memcpy(dst_pixels, src_pixels, skbitmap.getSize()); |
| 85 |
| 86 return skbitmap; |
| 87 } |
| 88 |
| 89 SkBitmap CreateSkBitmapFromResource(const char* name) { |
| 90 return ConvertToSkBitmap(CreateJavaBitmapFromResource(name)); |
| 91 } |
| 92 |
| 101 } // namespace gfx | 93 } // namespace gfx |
| OLD | NEW |