1a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon/* 2a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * Copyright (C) 2012 The Android Open Source Project 3a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * 4a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * Licensed under the Apache License, Version 2.0 (the "License"); 5a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * you may not use this file except in compliance with the License. 6a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * You may obtain a copy of the License at 7a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * 8a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * http://www.apache.org/licenses/LICENSE-2.0 9a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * 10a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * Unless required by applicable law or agreed to in writing, software 11a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * distributed under the License is distributed on an "AS IS" BASIS, 12a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * See the License for the specific language governing permissions and 14a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * limitations under the License. 15a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon */ 16a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 17a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon// Provides a webviewchromium glue layer adapter from the internal Android 18a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon// GL Functor data types into the types the chromium stack expects, and back. 19a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 20a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon#define LOG_TAG "webviewchromium_plat_support" 21a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 22a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon#include "android_webview/public/browser/draw_gl.h" 23a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 24d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu#include <errno.h> 25a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon#include <jni.h> 26a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon#include <private/hwui/DrawGlInfo.h> 27d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu#include <string.h> 28d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu#include <sys/resource.h> 29d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu#include <sys/time.h> 30a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon#include <utils/Functor.h> 31a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon#include <utils/Log.h> 32a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 33a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) 34a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon#define COMPILE_ASSERT(expr, err) static const char err[(expr) ? 1 : -1] = ""; 35a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 36a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonnamespace android { 37a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonnamespace { 38a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 39a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan DixonAwDrawGLFunction* g_aw_drawgl_function = NULL; 40a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 41a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonclass DrawGLFunctor : public Functor { 42a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon public: 43a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon DrawGLFunctor(jint view_context) : view_context_(view_context) {} 44a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon virtual ~DrawGLFunctor() {} 45a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 46a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Functor 47a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon virtual status_t operator ()(int what, void* data) { 48a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon using uirenderer::DrawGlInfo; 49a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon if (!g_aw_drawgl_function) { 50a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon ALOGE("Cannot draw: no DrawGL Function installed"); 51a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon return DrawGlInfo::kStatusDone; 52a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 53a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 54a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon AwDrawGLInfo aw_info; 55a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.mode = (what == DrawGlInfo::kModeProcess) ? 56a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon AwDrawGLInfo::kModeProcess : AwDrawGLInfo::kModeDraw; 57a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon DrawGlInfo* gl_info = reinterpret_cast<DrawGlInfo*>(data); 58a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 59a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Map across the input values. 60a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.clip_left = gl_info->clipLeft; 61a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.clip_top = gl_info->clipTop; 62a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.clip_right = gl_info->clipRight; 63a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.clip_bottom = gl_info->clipBottom; 64a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.width = gl_info->width; 65a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.height = gl_info->height; 66a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.is_layer = gl_info->isLayer; 67a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon COMPILE_ASSERT(NELEM(aw_info.transform) == NELEM(gl_info->transform), 68a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mismatched_transform_matrix_sizes); 69a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon for (int i = 0; i < NELEM(aw_info.transform); ++i) { 70a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.transform[i] = gl_info->transform[i]; 71a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 72a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 73a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Also pre-initialize the output fields in case the implementation does 74a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // not modify them. 75a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.status_mask = AwDrawGLInfo::kStatusMaskDone; 76a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.dirty_left = gl_info->dirtyLeft; 77a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.dirty_top = gl_info->dirtyTop; 78a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.dirty_right = gl_info->dirtyRight; 79a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon aw_info.dirty_bottom = gl_info->dirtyBottom; 80a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 81a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Invoke the DrawGL method. 82a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon g_aw_drawgl_function(view_context_, &aw_info, NULL); 83a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 84a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Copy out the outputs. 85a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon gl_info->dirtyLeft = aw_info.dirty_left; 86a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon gl_info->dirtyTop = aw_info.dirty_top; 87a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon gl_info->dirtyRight = aw_info.dirty_right; 88a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon gl_info->dirtyBottom = aw_info.dirty_bottom; 89a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 90a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Calculate the return code. 91a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon status_t res = DrawGlInfo::kStatusDone; 92a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon if (aw_info.status_mask & AwDrawGLInfo::kStatusMaskDraw) 93a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon res |= DrawGlInfo::kStatusDraw; 94a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon if (aw_info.status_mask & AwDrawGLInfo::kStatusMaskInvoke) 95a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon res |= DrawGlInfo::kStatusInvoke; 96a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 97a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon return res; 98a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 99a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 100a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon private: 101a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon int view_context_; 102a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon}; 103a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 104d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu// Raise the file handle soft limit to the hard limit since gralloc buffers 105d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu// uses file handles. 106d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liuvoid RaiseFileNumberLimit() { 107d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu static bool have_raised_limit = false; 108d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu if (have_raised_limit) 109d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu return; 110d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu 111d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu have_raised_limit = true; 112d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu struct rlimit limit_struct; 113d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu limit_struct.rlim_cur = 0; 114d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu limit_struct.rlim_max = 0; 115d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu if (getrlimit(RLIMIT_NOFILE, &limit_struct) == 0) { 116d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu limit_struct.rlim_cur = limit_struct.rlim_max; 117d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu if (setrlimit(RLIMIT_NOFILE, &limit_struct) != 0) { 118d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu ALOGE("setrlimit failed: %s", strerror(errno)); 119d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu } 120d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu } else { 121d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu ALOGE("getrlimit failed: %s", strerror(errno)); 122d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu } 123d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu} 124d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu 125a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonjint CreateGLFunctor(JNIEnv*, jclass, jint view_context) { 126d18983cc7040f96a2283c0a318f25fe4474d72ffBo Liu RaiseFileNumberLimit(); 127a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon return reinterpret_cast<jint>(new DrawGLFunctor(view_context)); 128a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon} 129a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 130a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonvoid DestroyGLFunctor(JNIEnv*, jclass, jint functor) { 131a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon delete reinterpret_cast<DrawGLFunctor*>(functor); 132a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon} 133a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 134a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonvoid SetChromiumAwDrawGLFunction(JNIEnv*, jclass, jint draw_function) { 135a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon g_aw_drawgl_function = reinterpret_cast<AwDrawGLFunction*>(draw_function); 136a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon} 137a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 138a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonconst char kClassName[] = "com/android/webview/chromium/DrawGLFunctor"; 139a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonconst JNINativeMethod kJniMethods[] = { 140a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon { "nativeCreateGLFunctor", "(I)I", 141991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon reinterpret_cast<void*>(CreateGLFunctor) }, 142a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon { "nativeDestroyGLFunctor", "(I)V", 143991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon reinterpret_cast<void*>(DestroyGLFunctor) }, 144a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon { "nativeSetChromiumAwDrawGLFunction", "(I)V", 145991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon reinterpret_cast<void*>(SetChromiumAwDrawGLFunction) }, 146a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon}; 147a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 148a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon} // namespace 149a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 150a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonvoid RegisterDrawGLFunctor(JNIEnv* env) { 151a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon jclass clazz = env->FindClass(kClassName); 152a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName); 153a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 154a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods)); 155a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res); 156a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon} 157a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 158a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon} // namespace android 159