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:
DrawGLFunctor(jlong view_context)43 DrawGLFunctor(jlong view_context) : view_context_(view_context) {}
~DrawGLFunctor()44 virtual ~DrawGLFunctor() {}
45
46 // Functor
operator ()(int what,void * data)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.
RaiseFileNumberLimit()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
CreateGLFunctor(JNIEnv *,jclass,jlong view_context)121 jlong CreateGLFunctor(JNIEnv*, jclass, jlong view_context) {
122 RaiseFileNumberLimit();
123 return reinterpret_cast<jlong>(new DrawGLFunctor(view_context));
124 }
125
DestroyGLFunctor(JNIEnv *,jclass,jlong functor)126 void DestroyGLFunctor(JNIEnv*, jclass, jlong functor) {
127 delete reinterpret_cast<DrawGLFunctor*>(functor);
128 }
129
SetChromiumAwDrawGLFunction(JNIEnv *,jclass,jlong draw_function)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
RegisterDrawGLFunctor(JNIEnv * env)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