graphics_utils.cpp revision 364e97a049927e74db4888d19c2f4cee17e91a27
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>
285c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon#include <utils/UniquePtr.h>
295c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon#include <utils/Vector.h>
30c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu#include "graphic_buffer_impl.h"
31991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#include "GraphicsJNI.h"
32f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil#include "SkGraphics.h"
33f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil#include "SkPicture.h"
34991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
35991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
36991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
37991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonnamespace android {
38991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonnamespace {
39991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
405c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixonclass PixelInfo : public AwPixelInfo {
415c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon public:
425c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  PixelInfo(SkCanvas* canvas, const SkBitmap* bitmap);
435c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  ~PixelInfo();
445c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
455c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  void AddRectToClip(const SkIRect& rect);
465c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
475c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon private:
48991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  const SkBitmap* bitmap_;
495c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  SkAutoLockPixels bitmap_locker_;
505c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  Vector<int> clip_rect_storage_;
51991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon};
52991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
535c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixonclass ClipValidator : public SkCanvas::ClipVisitor {
545c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon public:
555c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  ClipValidator() : failed_(false) {}
565c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  bool failed() { return failed_; }
575c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
585c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  // ClipVisitor
595c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  virtual void clipRect(const SkRect& rect, SkRegion::Op op, bool antialias) {
605c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    failed_ |= antialias;
615c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  }
625c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
635c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) {
645c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    failed_ |= antialias;
655c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  }
665c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
675c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon private:
685c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  bool failed_;
695c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon};
705c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
715c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan DixonPixelInfo::PixelInfo(SkCanvas* canvas, const SkBitmap* bitmap)
725c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    : bitmap_(bitmap),
73364e97a049927e74db4888d19c2f4cee17e91a27Jonathan Dixon      bitmap_locker_(*bitmap) {
74364e97a049927e74db4888d19c2f4cee17e91a27Jonathan Dixon  memset(this, 0, sizeof(AwPixelInfo));
75364e97a049927e74db4888d19c2f4cee17e91a27Jonathan Dixon  version = kAwPixelInfoVersion;
76364e97a049927e74db4888d19c2f4cee17e91a27Jonathan Dixon}
775c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
785c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan DixonPixelInfo::~PixelInfo() {}
795c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
805c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixonvoid PixelInfo::AddRectToClip(const SkIRect& rect) {
815c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  ALOG_ASSERT(rect.width() >= 0 && rect.height() >= 0);
825c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  clip_rect_storage_.push_back(rect.x());
835c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  clip_rect_storage_.push_back(rect.y());
845c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  clip_rect_storage_.push_back(rect.width());
855c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  clip_rect_storage_.push_back(rect.height());
865c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  clip_rects = const_cast<int*>(clip_rect_storage_.array());
875c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  clip_rect_count = clip_rect_storage_.size() / 4;
885c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon}
895c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
905c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan DixonPixelInfo* TryToCreatePixelInfo(SkCanvas* canvas) {
915c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  // Check the clip can decompose into simple rectangles. This validator is
925c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  // not a perfect guarantee, but it's the closest I can do with the current
935c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  // API. TODO: compile this out in release builds as currently Java canvases
945c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  // do not allow for antialiased clip.
955c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  ClipValidator validator;
965c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  canvas->replayClips(&validator);
975c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  if (validator.failed())
985c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    return NULL;
995c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
10052dbec0d199461e4631cec25f8f0706c8ece3029Jonathan Dixon  SkCanvas::LayerIter layer(SkCanvas::LayerIter(canvas, false));
1015c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  if (layer.done())
1025c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    return NULL;
10352dbec0d199461e4631cec25f8f0706c8ece3029Jonathan Dixon  SkDevice* device = layer.device();
1045c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  if (!device)
1055c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    return NULL;
106991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  const SkBitmap* bitmap = &device->accessBitmap(true);
1075c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  if (!bitmap->lockPixelsAreWritable())
1085c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    return NULL;
1095c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
1105c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  UniquePtr<PixelInfo> pixels(new PixelInfo(canvas, bitmap));
1115c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  pixels->config =
1125c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon      bitmap->config() == SkBitmap::kARGB_8888_Config ? AwConfig_ARGB_8888 :
1135c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon      bitmap->config() == SkBitmap::kARGB_4444_Config ? AwConfig_ARGB_4444 :
1145c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon      bitmap->config() == SkBitmap::kRGB_565_Config ? AwConfig_RGB_565 : -1;
1155c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  if (pixels->config < 0)
1165c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    return NULL;
117991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
118991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  pixels->width = bitmap->width();
119991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  pixels->height = bitmap->height();
120991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  pixels->row_bytes = bitmap->rowBytes();
121991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  pixels->pixels = bitmap->getPixels();
12252dbec0d199461e4631cec25f8f0706c8ece3029Jonathan Dixon  const SkMatrix& matrix = layer.matrix();
123991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  for (int i = 0; i < 9; i++) {
124991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon    pixels->matrix[i] = matrix.get(i);
125991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  }
12652dbec0d199461e4631cec25f8f0706c8ece3029Jonathan Dixon
12752dbec0d199461e4631cec25f8f0706c8ece3029Jonathan Dixon  const SkRegion& region = layer.clip();
1285c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  if (region.isEmpty()) {
1295c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    pixels->AddRectToClip(region.getBounds());
1305c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  } else {
1315c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    SkRegion::Iterator clip_iterator(region);
1325c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    for (; !clip_iterator.done(); clip_iterator.next()) {
1335c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon      pixels->AddRectToClip(clip_iterator.rect());
1345c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    }
135991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  }
1365c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
137991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  // WebViewClassic used the DrawFilter for its own purposes (e.g. disabling
138991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  // dithering when zooming/scrolling) so for now at least, just ignore any
139991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  // client supplied DrawFilter.
140991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  ALOGW_IF(canvas->getDrawFilter(),
141991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon           "DrawFilter not supported in webviewchromium, will be ignored");
1425c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  return pixels.release();
1435c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon}
1445c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
1455c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan DixonAwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) {
1465c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, java_canvas);
1475c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  if (!canvas)
1485c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon    return NULL;
1495c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon
1505c324e7af9e99afec4caf6cd48aecf2d1a596b28Jonathan Dixon  return TryToCreatePixelInfo(canvas);
151991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
152991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
153991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonvoid ReleasePixels(AwPixelInfo* pixels) {
154991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  delete static_cast<PixelInfo*>(pixels);
155991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
156991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
157f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Giljobject CreatePicture(JNIEnv* env, SkPicture* picture) {
158f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  jclass clazz = env->FindClass("android/graphics/Picture");
159f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  jmethodID constructor = env->GetMethodID(clazz, "<init>", "(IZ)V");
160f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  ALOG_ASSERT(clazz);
161f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  ALOG_ASSERT(constructor);
162f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  return env->NewObject(clazz, constructor, picture, false);
163f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil}
164f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil
165f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gilbool IsSkiaVersionCompatible(SkiaVersionFunction function) {
166f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  bool compatible = false;
167f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  if (function && function == &SkGraphics::GetVersion) {
168f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil    int android_major, android_minor, android_patch;
169f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil    SkGraphics::GetVersion(&android_major, &android_minor, &android_patch);
170f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil
171f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil    int chromium_major, chromium_minor, chromium_patch;
172f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil    (*function)(&chromium_major, &chromium_minor, &chromium_patch);
173f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil
174f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil    compatible = android_major == chromium_major &&
175f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil                 android_minor == chromium_minor &&
176f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil                 android_patch == chromium_patch;
177f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  }
178f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil  return compatible;
179f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil}
180f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil
181991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonjint GetDrawSWFunctionTable(JNIEnv* env, jclass) {
182991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  static const AwDrawSWFunctionTable function_table = {
183991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon      &GetPixels,
184991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon      &ReleasePixels,
185f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil      &CreatePicture,
186f15e28c8d30c2ccea58871c9d22f8b47e53d6ea4Leandro Gracia Gil      &IsSkiaVersionCompatible,
187991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  };
188991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  return reinterpret_cast<jint>(&function_table);
189991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
190991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
191c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglujint GetDrawGLFunctionTable(JNIEnv* env, jclass) {
192c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu  static const AwDrawGLFunctionTable function_table = {
1931cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::Create,
1941cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::Release,
1951cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::MapStatic,
1961cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::UnmapStatic,
1971cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::GetNativeBufferStatic,
1981cc1c4153a26307948af9f1ee6d9cde7a7103b94Kaan Baloglu    &GraphicBufferImpl::GetStrideStatic,
199c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu  };
200c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu  return reinterpret_cast<jint>(&function_table);
201c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu}
202c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu
203991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonconst char kClassName[] = "com/android/webview/chromium/GraphicsUtils";
204991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonconst JNINativeMethod kJniMethods[] = {
205991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon    { "nativeGetDrawSWFunctionTable", "()I",
206991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon        reinterpret_cast<void*>(GetDrawSWFunctionTable) },
207c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu    { "nativeGetDrawGLFunctionTable", "()I",
208c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu        reinterpret_cast<void*>(GetDrawGLFunctionTable) },
209991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon};
210991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
211991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}  // namespace
212991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
213991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixonvoid RegisterGraphicsUtils(JNIEnv* env) {
214991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  jclass clazz = env->FindClass(kClassName);
215991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName);
216991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
217991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));
218991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon  LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res);
219991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}
220991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon
221991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon}  // namespace android
222