1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
android_webview / browser / gfx / aw_gl_surface.cc [blame]
// Copyright 2013 The Chromium Authors
// 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/aw_gl_surface.h"
#include <utility>
#include "android_webview/browser/gfx/scoped_app_gl_state_restore.h"
#include "ui/gl/gl_bindings.h"
#define EGL_EXTERNAL_SURFACE_ANGLE 0x348F
namespace android_webview {
AwGLSurface::AwGLSurface(gl::GLDisplayEGL* display, bool is_angle)
: gl::GLSurfaceEGL(display), is_angle_(is_angle) {}
AwGLSurface::AwGLSurface(gl::GLDisplayEGL* display,
scoped_refptr<gl::GLSurface> surface)
: gl::GLSurfaceEGL(display),
is_angle_(false),
wrapped_surface_(std::move(surface)) {}
AwGLSurface::~AwGLSurface() {
InvalidateWeakPtrs();
Destroy();
}
bool AwGLSurface::Initialize(gl::GLSurfaceFormat format) {
if (!is_angle_)
return true;
Destroy();
EGLint attribs[] = {EGL_WIDTH, size_.width(), EGL_HEIGHT,
size_.height(), EGL_NONE, EGL_NONE};
surface_ = eglCreatePbufferFromClientBuffer(GetGLDisplay()->GetDisplay(),
EGL_EXTERNAL_SURFACE_ANGLE,
nullptr, GetConfig(), attribs);
DCHECK_NE(surface_, EGL_NO_SURFACE);
return surface_ != EGL_NO_SURFACE;
}
void AwGLSurface::Destroy() {
if (surface_) {
eglDestroySurface(GetGLDisplay()->GetDisplay(), surface_);
surface_ = nullptr;
}
}
bool AwGLSurface::IsOffscreen() {
return true;
}
unsigned int AwGLSurface::GetBackingFramebufferObject() {
return ScopedAppGLStateRestore::Current()->framebuffer_binding_ext();
}
gfx::SwapResult AwGLSurface::SwapBuffers(PresentationCallback callback,
gfx::FrameData data) {
DCHECK(!pending_presentation_callback_);
pending_presentation_callback_ = std::move(callback);
return gfx::SwapResult::SWAP_ACK;
}
gfx::Size AwGLSurface::GetSize() {
return size_;
}
void* AwGLSurface::GetHandle() {
if (wrapped_surface_)
return wrapped_surface_->GetHandle();
return surface_;
}
gl::GLDisplay* AwGLSurface::GetGLDisplay() {
if (wrapped_surface_)
return wrapped_surface_->GetGLDisplay();
if (!is_angle_)
return nullptr;
return gl::GLSurfaceEGL::GetGLDisplay();
}
gl::GLSurfaceFormat AwGLSurface::GetFormat() {
return gl::GLSurfaceFormat();
}
bool AwGLSurface::Resize(const gfx::Size& size,
float scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) {
if (size_ == size)
return true;
size_ = size;
return Initialize(gl::GLSurfaceFormat());
}
bool AwGLSurface::OnMakeCurrent(gl::GLContext* context) {
if (!gl::GLSurfaceEGL::OnMakeCurrent(context))
return false;
return !wrapped_surface_ || wrapped_surface_->OnMakeCurrent(context);
}
void AwGLSurface::SetSize(const gfx::Size& size) {
size_ = size;
}
EGLConfig AwGLSurface::GetConfig() {
if (wrapped_surface_)
return wrapped_surface_->GetConfig();
if (!is_angle_)
return nullptr;
return gl::GLSurfaceEGL::GetConfig();
}
void AwGLSurface::MaybeDidPresent(const gfx::PresentationFeedback& feedback) {
if (!pending_presentation_callback_)
return;
std::move(pending_presentation_callback_).Run(feedback);
}
bool AwGLSurface::IsDrawingToFBO() {
return false;
}
} // namespace android_webview