graphics_utils.cpp revision 1cc1c4153a26307948af9f1ee6d9cde7a7103b94
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// Provides a webviewchromium glue layer adapter from the internal Android 18// graphics types into the types the chromium stack expects, and back. 19 20#define LOG_TAG "webviewchromium_plat_support" 21 22#include "android_webview/public/browser/draw_gl.h" 23#include "android_webview/public/browser/draw_sw.h" 24 25#include <cstdlib> 26#include <jni.h> 27#include <utils/Log.h> 28#include "graphic_buffer_impl.h" 29#include "GraphicsJNI.h" 30#include "SkGraphics.h" 31#include "SkPicture.h" 32 33#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) 34 35namespace android { 36namespace { 37 38struct PixelInfo : public AwPixelInfo { 39 PixelInfo(const SkBitmap* bitmap) 40 : bitmap_(bitmap) { 41 this->bitmap_->lockPixels(); 42 } 43 ~PixelInfo() { 44 this->bitmap_->unlockPixels(); 45 free(clip_region); 46 }; 47 const SkBitmap* bitmap_; 48}; 49 50AwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) { 51 SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, java_canvas); 52 if (!canvas) return NULL; 53 SkDevice* device = canvas->getDevice(); 54 if (!device) return NULL; 55 const SkBitmap* bitmap = &device->accessBitmap(true); 56 if (!bitmap->lockPixelsAreWritable()) return NULL; 57 58 PixelInfo* pixels = new PixelInfo(bitmap); 59 pixels->config = bitmap->config(); 60 pixels->width = bitmap->width(); 61 pixels->height = bitmap->height(); 62 pixels->row_bytes = bitmap->rowBytes(); 63 pixels->pixels = bitmap->getPixels(); 64 const SkMatrix& matrix = canvas->getTotalMatrix(); 65 for (int i = 0; i < 9; i++) { 66 pixels->matrix[i] = matrix.get(i); 67 } 68 // TODO: getTotalClip() is now marked as deprecated, but the replacement, 69 // getClipDeviceBounds, does not return the exact region, just the bounds. 70 // Work out what we should use instead. 71 const SkRegion& region = canvas->getTotalClip(); 72 pixels->clip_region = NULL; 73 pixels->clip_region_size = region.writeToMemory(NULL); 74 if (pixels->clip_region_size) { 75 pixels->clip_region = malloc(pixels->clip_region_size); 76 size_t written = region.writeToMemory(pixels->clip_region); 77 ALOG_ASSERT(written == pixels->clip_region_size); 78 } 79 // WebViewClassic used the DrawFilter for its own purposes (e.g. disabling 80 // dithering when zooming/scrolling) so for now at least, just ignore any 81 // client supplied DrawFilter. 82 ALOGW_IF(canvas->getDrawFilter(), 83 "DrawFilter not supported in webviewchromium, will be ignored"); 84 return pixels; 85} 86 87void ReleasePixels(AwPixelInfo* pixels) { 88 delete static_cast<PixelInfo*>(pixels); 89} 90 91jobject CreatePicture(JNIEnv* env, SkPicture* picture) { 92 jclass clazz = env->FindClass("android/graphics/Picture"); 93 jmethodID constructor = env->GetMethodID(clazz, "<init>", "(IZ)V"); 94 ALOG_ASSERT(clazz); 95 ALOG_ASSERT(constructor); 96 return env->NewObject(clazz, constructor, picture, false); 97} 98 99bool IsSkiaVersionCompatible(SkiaVersionFunction function) { 100 bool compatible = false; 101 if (function && function == &SkGraphics::GetVersion) { 102 int android_major, android_minor, android_patch; 103 SkGraphics::GetVersion(&android_major, &android_minor, &android_patch); 104 105 int chromium_major, chromium_minor, chromium_patch; 106 (*function)(&chromium_major, &chromium_minor, &chromium_patch); 107 108 compatible = android_major == chromium_major && 109 android_minor == chromium_minor && 110 android_patch == chromium_patch; 111 } 112 return compatible; 113} 114 115jint GetDrawSWFunctionTable(JNIEnv* env, jclass) { 116 static const AwDrawSWFunctionTable function_table = { 117 &GetPixels, 118 &ReleasePixels, 119 &CreatePicture, 120 &IsSkiaVersionCompatible, 121 }; 122 return reinterpret_cast<jint>(&function_table); 123} 124 125jint GetDrawGLFunctionTable(JNIEnv* env, jclass) { 126 static const AwDrawGLFunctionTable function_table = { 127 &GraphicBufferImpl::Create, 128 &GraphicBufferImpl::Release, 129 &GraphicBufferImpl::MapStatic, 130 &GraphicBufferImpl::UnmapStatic, 131 &GraphicBufferImpl::GetNativeBufferStatic, 132 &GraphicBufferImpl::GetStrideStatic, 133 }; 134 return reinterpret_cast<jint>(&function_table); 135} 136 137const char kClassName[] = "com/android/webview/chromium/GraphicsUtils"; 138const JNINativeMethod kJniMethods[] = { 139 { "nativeGetDrawSWFunctionTable", "()I", 140 reinterpret_cast<void*>(GetDrawSWFunctionTable) }, 141 { "nativeGetDrawGLFunctionTable", "()I", 142 reinterpret_cast<void*>(GetDrawGLFunctionTable) }, 143}; 144 145} // namespace 146 147void RegisterGraphicsUtils(JNIEnv* env) { 148 jclass clazz = env->FindClass(kClassName); 149 LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName); 150 151 int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods)); 152 LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res); 153} 154 155} // namespace android 156