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