graphics_utils.cpp revision 58702ab5d6fe80a179dff41ec1741cf3cd7bf3df
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).
6686abeb66b6f8237f85ccce79495f15ace437a96aJonathan Dixon  if (!canvas->getTotalClip().isRect() ||
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) {
85991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  static const AwDrawSWFunctionTable function_table = {
86991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon      &GetPixels,
87991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon      &ReleasePixels,
88991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  };
892ddcc98cb29e567ea545b3eba2fedc576d1f5365Ross McIlroy  return reinterpret_cast<intptr_t>(&function_table);
90991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
91991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
922ddcc98cb29e567ea545b3eba2fedc576d1f5365Ross McIlroyjlong GetDrawGLFunctionTable(JNIEnv* env, jclass) {
93c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu  static const AwDrawGLFunctionTable function_table = {
941cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::Create,
951cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::Release,
961cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::MapStatic,
971cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::UnmapStatic,
981cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::GetNativeBufferStatic,
991cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::GetStrideStatic,
100c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu  };
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