draw_gl_functor.cpp revision 6d0b3e2ec99c0d6c11faa12f207246ee83d042ac
11b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams/* 21b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Copyright (C) 2012 The Android Open Source Project 31b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * 41b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 51b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * you may not use this file except in compliance with the License. 61b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * You may obtain a copy of the License at 71b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * 81b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * http://www.apache.org/licenses/LICENSE-2.0 91b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * 101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Unless required by applicable law or agreed to in writing, software 111b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * distributed under the License is distributed on an "AS IS" BASIS, 121b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * See the License for the specific language governing permissions and 141b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * limitations under the License. 151b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams */ 161b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 17efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet// Provides a webviewchromium glue layer adapter from the internal Android 181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams// GL Functor data types into the types the chromium stack expects, and back. 191b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 201f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet#define LOG_TAG "webviewchromium_plat_support" 211b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 22003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines#include "draw_gl.h" 23003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines 24003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines#include <errno.h> 252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#include <jni.h> 2680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines#include <private/hwui/DrawGlInfo.h> 271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <string.h> 281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <sys/resource.h> 29efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet#include <sys/time.h> 30efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet#include <utils/Functor.h> 3159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet#include <utils/Log.h> 3259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet 3359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) 3402a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines#define COMPILE_ASSERT(expr, err) static const char err[(expr) ? 1 : -1] = ""; 351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 3659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouilletnamespace android { 371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsnamespace { 38efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet 391c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt WalaAwDrawGLFunction* g_aw_drawgl_function = NULL; 401c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala 411c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Walaclass DrawGLFunctor : public Functor { 421c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala public: 431c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala explicit DrawGLFunctor(jlong view_context) : view_context_(view_context) {} 441c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala virtual ~DrawGLFunctor() {} 451c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala 461c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala // Functor 47efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet virtual status_t operator ()(int what, void* data) { 48efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet using uirenderer::DrawGlInfo; 49efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet if (!g_aw_drawgl_function) { 50efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet ALOGE("Cannot draw: no DrawGL Function installed"); 51efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet return DrawGlInfo::kStatusDone; 52efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet } 53efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet 54efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet AwDrawGLInfo aw_info; 55efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet aw_info.version = kAwDrawGLInfoVersion; 56efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet switch (what) { 57efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet case DrawGlInfo::kModeDraw: { 58efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet aw_info.mode = AwDrawGLInfo::kModeDraw; 59efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet DrawGlInfo* gl_info = reinterpret_cast<DrawGlInfo*>(data); 60efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet 61efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet // Map across the input values. 62efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet aw_info.clip_left = gl_info->clipLeft; 63efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet aw_info.clip_top = gl_info->clipTop; 647dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines aw_info.clip_right = gl_info->clipRight; 657dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines aw_info.clip_bottom = gl_info->clipBottom; 667dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines aw_info.width = gl_info->width; 677dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines aw_info.height = gl_info->height; 68efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet aw_info.is_layer = gl_info->isLayer; 69efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet COMPILE_ASSERT(NELEM(aw_info.transform) == NELEM(gl_info->transform), 70efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet mismatched_transform_matrix_sizes); 717dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines for (int i = 0; i < NELEM(aw_info.transform); ++i) { 727dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines aw_info.transform[i] = gl_info->transform[i]; 737dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines } 747dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines break; 75003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines } 767dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines case DrawGlInfo::kModeProcess: 777dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines aw_info.mode = AwDrawGLInfo::kModeProcess; 781f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet break; 791f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet case DrawGlInfo::kModeProcessNoContext: 801f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet aw_info.mode = AwDrawGLInfo::kModeProcessNoContext; 811f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet break; 82efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet case DrawGlInfo::kModeSync: 83efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet aw_info.mode = AwDrawGLInfo::kModeSync; 84efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet break; 852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet default: 867dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines ALOGE("Unexpected DrawGLInfo type %d", what); 872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return DrawGlInfo::kStatusDone; 887dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines } 897dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines 907dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines // Invoke the DrawGL method. 917dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines g_aw_drawgl_function(view_context_, &aw_info, NULL); 927dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines 93eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet return DrawGlInfo::kStatusDone; 94eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet } 951c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala 961c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala private: 971f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet intptr_t view_context_; 981c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala}; 99eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet 1001cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet// Raise the file handle soft limit to the hard limit since gralloc buffers 1011cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet// uses file handles. 1021cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RaiseFileNumberLimit() { 1031c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala static bool have_raised_limit = false; 1041c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala if (have_raised_limit) 1051cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet return; 1061c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala 1071c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala have_raised_limit = true; 1081cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet struct rlimit limit_struct; 1091cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet limit_struct.rlim_cur = 0; 1101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams limit_struct.rlim_max = 0; 1111c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala if (getrlimit(RLIMIT_NOFILE, &limit_struct) == 0) { 1121c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala limit_struct.rlim_cur = limit_struct.rlim_max; 1131c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala if (setrlimit(RLIMIT_NOFILE, &limit_struct) != 0) { 1141c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala ALOGE("setrlimit failed: %s", strerror(errno)); 11502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines } 1167dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines } else { 11780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines ALOGE("getrlimit failed: %s", strerror(errno)); 1182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 11980706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines} 12080706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines 12180706836b18127b5733d790613a5d1b9f97cbb1dStephen Hinesjlong CreateGLFunctor(JNIEnv*, jclass, jlong view_context) { 12280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines RaiseFileNumberLimit(); 12380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines return reinterpret_cast<jlong>(new DrawGLFunctor(view_context)); 12480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines} 12580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines 1267dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hinesvoid DestroyGLFunctor(JNIEnv*, jclass, jlong functor) { 127eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet delete reinterpret_cast<DrawGLFunctor*>(functor); 1287dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines} 1297dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines 1307dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hinesvoid SetChromiumAwDrawGLFunction(JNIEnv*, jclass, jlong draw_function) { 1317dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines g_aw_drawgl_function = reinterpret_cast<AwDrawGLFunction*>(draw_function); 1327dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines} 1331cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet 1341cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletconst char kClassName[] = "com/android/webview/chromium/DrawGLFunctor"; 1351cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletconst JNINativeMethod kJniMethods[] = { 1361cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet { "nativeCreateGLFunctor", "(J)J", 1371cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet reinterpret_cast<void*>(CreateGLFunctor) }, 1387dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines { "nativeDestroyGLFunctor", "(J)V", 1392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet reinterpret_cast<void*>(DestroyGLFunctor) }, 1407dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines { "nativeSetChromiumAwDrawGLFunction", "(J)V", 1417dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines reinterpret_cast<void*>(SetChromiumAwDrawGLFunction) }, 1422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}; 1437dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines 144003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines} // namespace 145003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines 146003ac666e57669d4312b5792068c3db302ee7b84Stephen Hinesvoid RegisterDrawGLFunctor(JNIEnv* env) { 147003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines jclass clazz = env->FindClass(kClassName); 1481c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName); 149003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines 150003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods)); 151003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res); 1522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} 1531b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} // namespace android 1551b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams