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