graphics_utils.cpp revision 991b0c63bb8c0b0d8577a255b026117e9f37cece
1991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon/* 2991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * Copyright (C) 2012 The Android Open Source Project 3991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * 4991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * Licensed under the Apache License, Version 2.0 (the "License"); 5991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * you may not use this file except in compliance with the License. 6991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * You may obtain a copy of the License at 7991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * 8991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * http://www.apache.org/licenses/LICENSE-2.0 9991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * 10991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * Unless required by applicable law or agreed to in writing, software 11991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * distributed under the License is distributed on an "AS IS" BASIS, 12991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * See the License for the specific language governing permissions and 14991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon * limitations under the License. 15991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon */ 16991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 17991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon// Provides a webviewchromium glue layer adapter from the internal Android 18991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon// graphics types into the types the chromium stack expects, and back. 19991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 20991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#define LOG_TAG "webviewchromium_plat_support" 21991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 22991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include "android_webview/public/browser/draw_sw.h" 23991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 24991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include <cstdlib> 25991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include <jni.h> 26991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include <utils/Log.h> 27991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include "GraphicsJNI.h" 28991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 29991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) 30991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 31991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonnamespace android { 32991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonnamespace { 33991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 34991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonstruct PixelInfo : public AwPixelInfo { 35991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon PixelInfo(const SkBitmap* bitmap) 36991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon : bitmap_(bitmap) { 37991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon this->bitmap_->lockPixels(); 38991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon } 39991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon ~PixelInfo() { 40991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon this->bitmap_->unlockPixels(); 41991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon free(clip_region); 42991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon }; 43991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon const SkBitmap* bitmap_; 44991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}; 45991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 46991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan DixonAwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) { 47991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, java_canvas); 48991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon if (!canvas) return NULL; 49991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon SkDevice* device = canvas->getDevice(); 50991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon if (!device) return NULL; 51991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon const SkBitmap* bitmap = &device->accessBitmap(true); 52991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon if (!bitmap->lockPixelsAreWritable()) return NULL; 53991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 54991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon PixelInfo* pixels = new PixelInfo(bitmap); 55991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->config = bitmap->config(); 56991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->width = bitmap->width(); 57991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->height = bitmap->height(); 58991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->row_bytes = bitmap->rowBytes(); 59991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->pixels = bitmap->getPixels(); 60991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon const SkMatrix& matrix = canvas->getTotalMatrix(); 61991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon for (int i = 0; i < 9; i++) { 62991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->matrix[i] = matrix.get(i); 63991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon } 64991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon // TODO: getTotalClip() is now marked as deprecated, but the replacement, 65991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon // getClipDeviceBounds, does not return the exact region, just the bounds. 66991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon // Work out what we should use instead. 67991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon const SkRegion& region = canvas->getTotalClip(); 68991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->clip_region = NULL; 69991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->clip_region_size = region.writeToMemory(NULL); 70991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon if (pixels->clip_region_size) { 71991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon pixels->clip_region = malloc(pixels->clip_region_size); 72991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon size_t written = region.writeToMemory(pixels->clip_region); 73991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon ALOG_ASSERT(written == pixels->clip_region_size); 74991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon } 75991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon // WebViewClassic used the DrawFilter for its own purposes (e.g. disabling 76991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon // dithering when zooming/scrolling) so for now at least, just ignore any 77991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon // client supplied DrawFilter. 78991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon ALOGW_IF(canvas->getDrawFilter(), 79991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon "DrawFilter not supported in webviewchromium, will be ignored"); 80991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon return pixels; 81991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon} 82991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 83991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonvoid ReleasePixels(AwPixelInfo* pixels) { 84991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon delete static_cast<PixelInfo*>(pixels); 85991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon} 86991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 87991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonjint GetDrawSWFunctionTable(JNIEnv* env, jclass) { 88991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon static const AwDrawSWFunctionTable function_table = { 89991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon &GetPixels, 90991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon &ReleasePixels, 91991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon }; 92991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon return reinterpret_cast<jint>(&function_table); 93991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon} 94991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 95991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonconst char kClassName[] = "com/android/webview/chromium/GraphicsUtils"; 96991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonconst JNINativeMethod kJniMethods[] = { 97991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon { "nativeGetDrawSWFunctionTable", "()I", 98991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon reinterpret_cast<void*>(GetDrawSWFunctionTable) }, 99991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}; 100991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 101991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon} // namespace 102991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 103991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonvoid RegisterGraphicsUtils(JNIEnv* env) { 104991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon jclass clazz = env->FindClass(kClassName); 105991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName); 106991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 107991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods)); 108991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res); 109991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon} 110991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon 111991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon} // namespace android 112