1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/gl/gl_gl_api_implementation.h"
10 #include "base/command_line.h"
11 #include "base/string_util.h"
12 #include "ui/gl/gl_context.h"
13 #include "ui/gl/gl_state_restorer.h"
14 #include "ui/gl/gl_surface.h"
15 #include "ui/gl/gl_switches.h"
19 // The GL Api being used. This could be g_real_gl or gl_trace_gl
21 // A GL Api that calls directly into the driver.
22 static RealGLApi
* g_real_gl
;
23 // A GL Api that calls TRACE and then calls another GL api.
24 static TraceGLApi
* g_trace_gl
;
26 void InitializeGLBindingsGL() {
27 g_driver_gl
.InitializeBindings();
29 g_real_gl
= new RealGLApi();
30 g_trace_gl
= new TraceGLApi(g_real_gl
);
32 g_real_gl
->Initialize(&g_driver_gl
);
34 if (CommandLine::ForCurrentProcess()->HasSwitch(
35 switches::kEnableGPUServiceTracing
)) {
41 GLApi
* GetCurrentGLApi() {
42 return g_current_gl_context
;
45 void SetGLApi(GLApi
* api
) {
46 g_current_gl_context
= api
;
49 void SetGLToRealGLApi() {
53 void InitializeGLExtensionBindingsGL(GLContext
* context
) {
54 g_driver_gl
.InitializeExtensionBindings(context
);
57 void InitializeDebugGLBindingsGL() {
58 g_driver_gl
.InitializeDebugBindings();
61 void ClearGLBindingsGL() {
71 g_current_gl_context
= NULL
;
72 g_driver_gl
.ClearBindings();
81 GLApiBase::GLApiBase()
85 GLApiBase::~GLApiBase() {
88 void GLApiBase::InitializeBase(DriverGL
* driver
) {
92 RealGLApi::RealGLApi() {
95 RealGLApi::~RealGLApi() {
98 void RealGLApi::Initialize(DriverGL
* driver
) {
99 InitializeBase(driver
);
102 TraceGLApi::~TraceGLApi() {
105 VirtualGLApi::VirtualGLApi()
106 : real_context_(NULL
),
107 current_context_(NULL
) {
110 VirtualGLApi::~VirtualGLApi() {
113 void VirtualGLApi::Initialize(DriverGL
* driver
, GLContext
* real_context
) {
114 InitializeBase(driver
);
115 real_context_
= real_context
;
117 DCHECK(real_context
->IsCurrent(NULL
));
118 std::string
ext_string(
119 reinterpret_cast<const char*>(driver_
->fn
.glGetStringFn(GL_EXTENSIONS
)));
120 std::vector
<std::string
> ext
;
121 Tokenize(ext_string
, " ", &ext
);
123 std::vector
<std::string
>::iterator it
;
124 // We can't support GL_EXT_occlusion_query_boolean which is
125 // based on GL_ARB_occlusion_query without a lot of work virtualizing
127 it
= std::find(ext
.begin(), ext
.end(), "GL_EXT_occlusion_query_boolean");
131 extensions_
= JoinString(ext
, " ");
134 bool VirtualGLApi::MakeCurrent(GLContext
* virtual_context
, GLSurface
* surface
) {
135 bool switched_contexts
= g_current_gl_context
!= this;
136 GLSurface
* current_surface
= GLSurface::GetCurrent();
137 if (switched_contexts
|| surface
!= current_surface
) {
138 if (!switched_contexts
&& current_surface
&&
139 virtual_context
->IsCurrent(surface
)) {
140 // MakeCurrent 'lite' path that avoids potentially expensive MakeCurrent()
141 // calls if the GLSurface uses the same underlying surface or renders to
143 if (!surface
->OnMakeCurrent(real_context_
)) {
144 LOG(ERROR
) << "Could not make GLSurface current.";
147 } else if (!real_context_
->MakeCurrent(surface
)) {
152 DCHECK(GLSurface::GetCurrent());
153 DCHECK(real_context_
->IsCurrent(GLSurface::GetCurrent()));
154 DCHECK(virtual_context
->IsCurrent(surface
));
156 if (switched_contexts
|| virtual_context
!= current_context_
) {
157 // There should be no errors from the previous context leaking into the
159 DCHECK_EQ(glGetErrorFn(), static_cast<GLenum
>(GL_NO_ERROR
));
161 current_context_
= virtual_context
;
162 // Set all state that is different from the real state
163 // NOTE: !!! This is a temporary implementation that just restores all
164 // state to let us test that it works.
165 // TODO: ASAP, change this to something that only restores the state
166 // needed for individual GL calls.
167 GLApi
* temp
= GetCurrentGLApi();
169 virtual_context
->GetGLStateRestorer()->RestoreState();
176 void VirtualGLApi::OnDestroyVirtualContext(GLContext
* virtual_context
) {
177 if (current_context_
== virtual_context
)
178 current_context_
= NULL
;
181 const GLubyte
* VirtualGLApi::glGetStringFn(GLenum name
) {
184 return reinterpret_cast<const GLubyte
*>(extensions_
.c_str());
186 return driver_
->fn
.glGetStringFn(name
);