graphics_utils.cpp revision df44c7670d1fa36fffb614ce04bf16ba25ef65d0
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
22c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu#include "android_webview/public/browser/draw_gl.h"
23991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include "android_webview/public/browser/draw_sw.h"
24991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
25991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include <cstdlib>
26991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include <jni.h>
27991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include <utils/Log.h>
28c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu#include "graphic_buffer_impl.h"
29991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include "GraphicsJNI.h"
30a4f187ef3723a330f2145cea5a4f83e486199137Jonathan Dixon#include "SkCanvasStateUtils.h"
31f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil#include "SkGraphics.h"
32f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil#include "SkPicture.h"
33991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
34991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
35991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
36991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonnamespace android {
37991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonnamespace {
38991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
395c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixonclass PixelInfo : public AwPixelInfo {
405c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon public:
41a4f187ef3723a330f2145cea5a4f83e486199137Jonathan Dixon  PixelInfo(SkCanvas* canvas);
425c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  ~PixelInfo();
43991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon};
44991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
455c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
46a4f187ef3723a330f2145cea5a4f83e486199137Jonathan DixonPixelInfo::PixelInfo(SkCanvas* canvas) {
47364e97a049927e74db4888d19c2f4cee17e91a27Jonathan Dixon  memset(this, 0, sizeof(AwPixelInfo));
48364e97a049927e74db4888d19c2f4cee17e91a27Jonathan Dixon  version = kAwPixelInfoVersion;
49a4f187ef3723a330f2145cea5a4f83e486199137Jonathan Dixon  state = SkCanvasStateUtils::CaptureCanvasState(canvas);
50364e97a049927e74db4888d19c2f4cee17e91a27Jonathan Dixon}
515c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
52a4f187ef3723a330f2145cea5a4f83e486199137Jonathan DixonPixelInfo::~PixelInfo() {
53a4f187ef3723a330f2145cea5a4f83e486199137Jonathan Dixon  if (state)
54a4f187ef3723a330f2145cea5a4f83e486199137Jonathan Dixon    SkCanvasStateUtils::ReleaseCanvasState(state);
555c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon}
565c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
575c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan DixonAwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) {
585c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, java_canvas);
595c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  if (!canvas)
605c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    return NULL;
615c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
6286abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon  // Workarounds for http://crbug.com/271096: SW draw only supports
6386abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon  // translate & scale transforms, and a simple rectangular clip.
6486abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon  // (This also avoids significant wasted time in calling
6586abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon  // SkCanvasStateUtils::CaptureCanvasState when the clip is complex).
66e841604a0e87664b009fe713167db941a41604b4Leon Scroggins  if (!canvas->isClipRect() ||
6786abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon      (canvas->getTotalMatrix().getType() &
6886abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon                ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))) {
6986abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon    return NULL;
7086abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon  }
7186abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon
728ec5fb8559251164082b3f050c090ceb740a14e8Ben Murdoch  PixelInfo* pixels = new PixelInfo(canvas);
738ec5fb8559251164082b3f050c090ceb740a14e8Ben Murdoch  if (!pixels->state) {
748ec5fb8559251164082b3f050c090ceb740a14e8Ben Murdoch      delete pixels;
758ec5fb8559251164082b3f050c090ceb740a14e8Ben Murdoch      pixels = NULL;
768ec5fb8559251164082b3f050c090ceb740a14e8Ben Murdoch  }
778ec5fb8559251164082b3f050c090ceb740a14e8Ben Murdoch  return pixels;
78991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
79991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
80991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonvoid ReleasePixels(AwPixelInfo* pixels) {
81991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  delete static_cast<PixelInfo*>(pixels);
82991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
83991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
842ddcc98cb29e567ea545b3eba2fedc576d1f5365Ross McIlroyjlong GetDrawSWFunctionTable(JNIEnv* env, jclass) {
854cb347aeb733d199418472de549c24a31d3e7477Bo Liu  static AwDrawSWFunctionTable function_table;
86df44c7670d1fa36fffb614ce04bf16ba25ef65d0Bo Liu  function_table.version = kAwDrawSWFunctionTableVersion;
874cb347aeb733d199418472de549c24a31d3e7477Bo Liu  function_table.access_pixels = &GetPixels;
884cb347aeb733d199418472de549c24a31d3e7477Bo Liu  function_table.release_pixels = &ReleasePixels;
892ddcc98cb29e567ea545b3eba2fedc576d1f5365Ross McIlroy  return reinterpret_cast<intptr_t>(&function_table);
90991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
91991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
922ddcc98cb29e567ea545b3eba2fedc576d1f5365Ross McIlroyjlong GetDrawGLFunctionTable(JNIEnv* env, jclass) {
934cb347aeb733d199418472de549c24a31d3e7477Bo Liu  static AwDrawGLFunctionTable function_table;
94df44c7670d1fa36fffb614ce04bf16ba25ef65d0Bo Liu  function_table.version = kAwDrawGLFunctionTableVersion;
954cb347aeb733d199418472de549c24a31d3e7477Bo Liu  function_table.create_graphic_buffer = &GraphicBufferImpl::Create;
964cb347aeb733d199418472de549c24a31d3e7477Bo Liu  function_table.release_graphic_buffer = &GraphicBufferImpl::Release;
974cb347aeb733d199418472de549c24a31d3e7477Bo Liu  function_table.map = &GraphicBufferImpl::MapStatic;
984cb347aeb733d199418472de549c24a31d3e7477Bo Liu  function_table.unmap = &GraphicBufferImpl::UnmapStatic;
994cb347aeb733d199418472de549c24a31d3e7477Bo Liu  function_table.get_native_buffer = &GraphicBufferImpl::GetNativeBufferStatic;
1004cb347aeb733d199418472de549c24a31d3e7477Bo Liu  function_table.get_stride = &GraphicBufferImpl::GetStrideStatic;
1012ddcc98cb29e567ea545b3eba2fedc576d1f5365Ross McIlroy  return reinterpret_cast<intptr_t>(&function_table);
102c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu}
103c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu
104991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonconst char kClassName[] = "com/android/webview/chromium/GraphicsUtils";
105991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonconst JNINativeMethod kJniMethods[] = {
10658702ab5d6fe80a179dff41ec1741cf3cd7bf3dfRoss McIlroy    { "nativeGetDrawSWFunctionTable", "()J",
107991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon        reinterpret_cast<void*>(GetDrawSWFunctionTable) },
10858702ab5d6fe80a179dff41ec1741cf3cd7bf3dfRoss McIlroy    { "nativeGetDrawGLFunctionTable", "()J",
109c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu        reinterpret_cast<void*>(GetDrawGLFunctionTable) },
110991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon};
111991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
112991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}  // namespace
113991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
114991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonvoid RegisterGraphicsUtils(JNIEnv* env) {
115991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  jclass clazz = env->FindClass(kClassName);
116991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName);
117991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
118991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));
119991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res);
120991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
121991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
122991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}  // namespace android
123