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