• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkCanvasStateUtils.h"
31 #include "SkGraphics.h"
32 #include "SkPicture.h"
33 
34 #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
35 
36 namespace android {
37 namespace {
38 
39 class PixelInfo : public AwPixelInfo {
40  public:
41   PixelInfo(SkCanvas* canvas);
42   ~PixelInfo();
43 };
44 
45 
PixelInfo(SkCanvas * canvas)46 PixelInfo::PixelInfo(SkCanvas* canvas) {
47   memset(this, 0, sizeof(AwPixelInfo));
48   version = kAwPixelInfoVersion;
49   state = SkCanvasStateUtils::CaptureCanvasState(canvas);
50 }
51 
~PixelInfo()52 PixelInfo::~PixelInfo() {
53   if (state)
54     SkCanvasStateUtils::ReleaseCanvasState(state);
55 }
56 
GetPixels(JNIEnv * env,jobject java_canvas)57 AwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) {
58   SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, java_canvas);
59   if (!canvas)
60     return NULL;
61 
62   // Workarounds for http://crbug.com/271096: SW draw only supports
63   // translate & scale transforms, and a simple rectangular clip.
64   // (This also avoids significant wasted time in calling
65   // SkCanvasStateUtils::CaptureCanvasState when the clip is complex).
66   if (!canvas->getTotalClip().isRect() ||
67       (canvas->getTotalMatrix().getType() &
68                 ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))) {
69     return NULL;
70   }
71 
72   PixelInfo* pixels = new PixelInfo(canvas);
73   if (!pixels->state) {
74       delete pixels;
75       pixels = NULL;
76   }
77   return pixels;
78 }
79 
ReleasePixels(AwPixelInfo * pixels)80 void ReleasePixels(AwPixelInfo* pixels) {
81   delete static_cast<PixelInfo*>(pixels);
82 }
83 
CreatePicture(JNIEnv * env,SkPicture * picture)84 jobject CreatePicture(JNIEnv* env, SkPicture* picture) {
85   jclass clazz = env->FindClass("android/graphics/Picture");
86   jmethodID constructor = env->GetMethodID(clazz, "<init>", "(IZ)V");
87   ALOG_ASSERT(clazz);
88   ALOG_ASSERT(constructor);
89   return env->NewObject(clazz, constructor, picture, false);
90 }
91 
IsSkiaVersionCompatible(SkiaVersionFunction function)92 bool IsSkiaVersionCompatible(SkiaVersionFunction function) {
93   bool compatible = false;
94   if (function && function == &SkGraphics::GetVersion) {
95     int android_major, android_minor, android_patch;
96     SkGraphics::GetVersion(&android_major, &android_minor, &android_patch);
97 
98     int chromium_major, chromium_minor, chromium_patch;
99     (*function)(&chromium_major, &chromium_minor, &chromium_patch);
100 
101     compatible = android_major == chromium_major &&
102                  android_minor == chromium_minor &&
103                  android_patch == chromium_patch;
104   }
105   return compatible;
106 }
107 
GetDrawSWFunctionTable(JNIEnv * env,jclass)108 jint GetDrawSWFunctionTable(JNIEnv* env, jclass) {
109   static const AwDrawSWFunctionTable function_table = {
110       &GetPixels,
111       &ReleasePixels,
112       &CreatePicture,
113       &IsSkiaVersionCompatible,
114   };
115   return reinterpret_cast<jint>(&function_table);
116 }
117 
GetDrawGLFunctionTable(JNIEnv * env,jclass)118 jint GetDrawGLFunctionTable(JNIEnv* env, jclass) {
119   static const AwDrawGLFunctionTable function_table = {
120     &GraphicBufferImpl::Create,
121     &GraphicBufferImpl::Release,
122     &GraphicBufferImpl::MapStatic,
123     &GraphicBufferImpl::UnmapStatic,
124     &GraphicBufferImpl::GetNativeBufferStatic,
125     &GraphicBufferImpl::GetStrideStatic,
126   };
127   return reinterpret_cast<jint>(&function_table);
128 }
129 
130 const char kClassName[] = "com/android/webview/chromium/GraphicsUtils";
131 const JNINativeMethod kJniMethods[] = {
132     { "nativeGetDrawSWFunctionTable", "()I",
133         reinterpret_cast<void*>(GetDrawSWFunctionTable) },
134     { "nativeGetDrawGLFunctionTable", "()I",
135         reinterpret_cast<void*>(GetDrawGLFunctionTable) },
136 };
137 
138 }  // namespace
139 
RegisterGraphicsUtils(JNIEnv * env)140 void RegisterGraphicsUtils(JNIEnv* env) {
141   jclass clazz = env->FindClass(kClassName);
142   LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName);
143 
144   int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));
145   LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res);
146 }
147 
148 }  // namespace android
149