123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "android_webview/browser/gfx/scoped_app_gl_state_restore_impl_angle.h"
- #include <EGL/egl.h>
- #include <GLES2/gl2.h>
- #include "base/android/build_info.h"
- #include "base/native_library.h"
- #include "base/threading/thread_restrictions.h"
- #include "ui/gl/gl_context.h"
- namespace android_webview {
- namespace {
- namespace os {
- // TODO(penghuang): remove this typedef when egl headers are updated to 1.5.
- typedef __eglMustCastToProperFunctionPointerType(
- EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC)(const char* procname);
- typedef EGLContext(EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC)(void);
- PFNEGLGETPROCADDRESSPROC eglGetProcAddressFn = nullptr;
- PFNGLGETBOOLEANVPROC glGetBooleanvFn = nullptr;
- PFNGLGETINTEGERVPROC glGetIntegervFn = nullptr;
- #if DCHECK_IS_ON()
- PFNEGLGETCURRENTCONTEXTPROC eglGetCurrentContextFn = nullptr;
- #endif
- template <typename T>
- void AssignProc(T& fn, const char* name) {
- fn = reinterpret_cast<T>(eglGetProcAddressFn(name));
- CHECK(fn) << "Failed to get " << name;
- }
- void InitializeGLBindings() {
- if (eglGetProcAddressFn)
- return;
- base::NativeLibraryLoadError error;
- base::FilePath filename("libEGL.so");
- base::NativeLibrary egl_library = base::LoadNativeLibrary(filename, &error);
- CHECK(egl_library) << "Failed to load " << filename.MaybeAsASCII() << ": "
- << error.ToString();
- eglGetProcAddressFn = reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(
- base::GetFunctionPointerFromNativeLibrary(egl_library,
- "eglGetProcAddress"));
- CHECK(eglGetProcAddressFn) << "Failed to get eglGetProcAddress.";
- AssignProc(glGetBooleanvFn, "glGetBooleanv");
- AssignProc(glGetIntegervFn, "glGetIntegerv");
- #if DCHECK_IS_ON()
- AssignProc(eglGetCurrentContextFn, "eglGetCurrentContext");
- #endif
- }
- } // namespace os
- } // namespace
- namespace internal {
- ScopedAppGLStateRestoreImplAngle::ScopedAppGLStateRestoreImplAngle(
- ScopedAppGLStateRestore::CallMode mode,
- bool save_restore) {
- os::InitializeGLBindings();
- #if DCHECK_IS_ON()
- egl_context_ = os::eglGetCurrentContextFn();
- DCHECK_NE(egl_context_, EGL_NO_CONTEXT) << " no native context is current.";
- #endif
- if (base::android::BuildInfo::GetInstance()->sdk_int() ==
- base::android::SDK_VERSION_S) {
- GLint red_bits = 0;
- GLint green_bits = 0;
- GLint blue_bits = 0;
- GLint alpha_bits = 0;
- os::glGetIntegervFn(GL_RED_BITS, &red_bits);
- os::glGetIntegervFn(GL_GREEN_BITS, &green_bits);
- os::glGetIntegervFn(GL_BLUE_BITS, &blue_bits);
- os::glGetIntegervFn(GL_ALPHA_BITS, &alpha_bits);
- skip_draw_ =
- red_bits == 8 && green_bits == 0 && blue_bits == 0 && alpha_bits == 0;
- }
- // Query |stencil_state_| with native GL API.
- // Android should have made a native EGL context current, so we can call GL
- // directly.
- os::glGetBooleanvFn(GL_STENCIL_TEST, &stencil_state_.stencil_test_enabled);
- os::glGetIntegervFn(GL_STENCIL_FUNC, &stencil_state_.stencil_front_func);
- os::glGetIntegervFn(GL_STENCIL_VALUE_MASK,
- &stencil_state_.stencil_front_mask);
- os::glGetIntegervFn(GL_STENCIL_REF, &stencil_state_.stencil_front_ref);
- os::glGetIntegervFn(GL_STENCIL_BACK_FUNC, &stencil_state_.stencil_back_func);
- os::glGetIntegervFn(GL_STENCIL_BACK_VALUE_MASK,
- &stencil_state_.stencil_back_mask);
- os::glGetIntegervFn(GL_STENCIL_BACK_REF, &stencil_state_.stencil_back_ref);
- os::glGetIntegervFn(GL_STENCIL_CLEAR_VALUE, &stencil_state_.stencil_clear);
- os::glGetIntegervFn(GL_STENCIL_WRITEMASK,
- &stencil_state_.stencil_front_writemask);
- os::glGetIntegervFn(GL_STENCIL_BACK_WRITEMASK,
- &stencil_state_.stencil_back_writemask);
- os::glGetIntegervFn(GL_STENCIL_FAIL, &stencil_state_.stencil_front_fail_op);
- os::glGetIntegervFn(GL_STENCIL_PASS_DEPTH_FAIL,
- &stencil_state_.stencil_front_z_fail_op);
- os::glGetIntegervFn(GL_STENCIL_PASS_DEPTH_PASS,
- &stencil_state_.stencil_front_z_pass_op);
- os::glGetIntegervFn(GL_STENCIL_BACK_FAIL,
- &stencil_state_.stencil_back_fail_op);
- os::glGetIntegervFn(GL_STENCIL_BACK_PASS_DEPTH_FAIL,
- &stencil_state_.stencil_back_z_fail_op);
- os::glGetIntegervFn(GL_STENCIL_BACK_PASS_DEPTH_PASS,
- &stencil_state_.stencil_back_z_pass_op);
- // ANGLE can wrap current native FBO to an EGLSurface which will be used
- // later, so with that EGLSurface as render target, the framebuffer binding is
- // always 0.
- framebuffer_binding_ext_ = 0;
- // There should be no gl::GLContext current.
- DCHECK(!gl::GLContext::GetCurrent());
- }
- ScopedAppGLStateRestoreImplAngle::~ScopedAppGLStateRestoreImplAngle() {
- // There should be no gl::GLContext current.
- DCHECK(!gl::GLContext::GetCurrent());
- #if DCHECK_IS_ON()
- DCHECK_EQ(egl_context_, os::eglGetCurrentContextFn())
- << " the native context is changed.";
- #endif
- }
- } // namespace internal
- } // namespace android_webview
|