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