Skip to content

Commit

Permalink
Virtual GL
Browse files Browse the repository at this point in the history
BUG=155557


Review URL: https://chromiumcodereview.appspot.com/11275120

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166442 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
gman@chromium.org committed Nov 7, 2012
1 parent e2c9267 commit 1868a34
Show file tree
Hide file tree
Showing 40 changed files with 1,669 additions and 58 deletions.
4 changes: 2 additions & 2 deletions gpu/command_buffer/build_gles2_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6529,14 +6529,14 @@ def WriteContextStateImpl(self, filename):
file.Write("}\n")

file.Write("""
void ContextState::InitCapabilities() {
void ContextState::InitCapabilities() const {
""")
for capability in _CAPABILITY_FLAGS:
file.Write(" EnableDisable(GL_%s, enable_flags.%s);\n" %
(capability['name'].upper(), capability['name']))
file.Write("""}
void ContextState::InitState() {
void ContextState::InitState() const {
""")

# We need to sort the keys so the expectations match
Expand Down
76 changes: 74 additions & 2 deletions gpu/command_buffer/service/context_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "gpu/command_buffer/service/context_state.h"

#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_implementation.h"

namespace gpu {
namespace gles2 {
Expand Down Expand Up @@ -32,8 +34,6 @@ ContextState::ContextState()
: pack_alignment(4),
unpack_alignment(4),
active_texture_unit(0),
viewport_max_width(0),
viewport_max_height(0),
hint_generate_mipmap(GL_DONT_CARE),
hint_fragment_shader_derivative(GL_DONT_CARE),
pack_reverse_row_order(false) {
Expand All @@ -43,6 +43,78 @@ ContextState::ContextState()
ContextState::~ContextState() {
}

void ContextState::RestoreState() const {
InitCapabilities();
InitState();

glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment);

glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
// TODO: If OES_standard_derivatives is available
// restore GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES

// Restore Texture state.
for (size_t ii = 0; ii < texture_units.size(); ++ii) {
const TextureUnit& texture_unit = texture_units[ii];
glActiveTexture(GL_TEXTURE0 + ii);
GLuint service_id = texture_unit.bound_texture_2d ?
texture_unit.bound_texture_2d->service_id() : 0;
glBindTexture(GL_TEXTURE_2D, service_id);
service_id = texture_unit.bound_texture_cube_map ?
texture_unit.bound_texture_cube_map->service_id() : 0;
glBindTexture(GL_TEXTURE_CUBE_MAP, service_id);
// TODO: Restore bindings for GL_TEXTURE_RECTANGLE_ARB and
// GL_TEXTURE_EXTERNAL_OES.
}
glActiveTexture(GL_TEXTURE0 + active_texture_unit);

// Restore Attrib State
// TODO: This if should not be needed. RestoreState is getting called
// before GLES2Decoder::Initialize which is a bug.
if (vertex_attrib_manager) {
for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs();
++attrib) {
const VertexAttribManager::VertexAttribInfo* info =
vertex_attrib_manager->GetVertexAttribInfo(attrib);
const void* ptr = reinterpret_cast<const void*>(info->offset());
BufferManager::BufferInfo* buffer_info = info->buffer();
glBindBuffer(
GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0);
glVertexAttribPointer(
attrib, info->size(), info->type(), info->normalized(),
info->gl_stride(), ptr);
if (info->divisor())
glVertexAttribDivisorANGLE(attrib, info->divisor());
// Never touch vertex attribute 0's state (in particular, never
// disable it) when running on desktop GL because it will never be
// re-enabled.
if (attrib != 0 ||
gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
if (info->enabled()) {
glEnableVertexAttribArray(attrib);
} else {
glDisableVertexAttribArray(attrib);
}
}
}
BufferManager::BufferInfo* element_array_buffer =
vertex_attrib_manager->element_array_buffer();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
element_array_buffer ? element_array_buffer->service_id() : 0);
}

// Restore Bindings
glBindBuffer(
GL_ARRAY_BUFFER,
bound_array_buffer ? bound_array_buffer->service_id() : 0);
glBindRenderbufferEXT(
GL_RENDERBUFFER,
bound_renderbuffer ? bound_renderbuffer->service_id() : 0);

glUseProgram(current_program ? current_program->service_id() : 0);
}

// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
// instead of having to edit some template or the code generator.
Expand Down
12 changes: 5 additions & 7 deletions gpu/command_buffer/service/context_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_H_
#define GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_H_

#include <vector>
#include "base/logging.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/buffer_manager.h"
Expand Down Expand Up @@ -83,8 +84,9 @@ struct GPU_EXPORT ContextState {

void Initialize();

void InitCapabilities();
void InitState();
void RestoreState() const;
void InitCapabilities() const;
void InitState() const;

#include "gpu/command_buffer/service/context_state_autogen.h"

Expand All @@ -101,16 +103,12 @@ struct GPU_EXPORT ContextState {
// be 2.
GLuint active_texture_unit;

// Cached values of the currently assigned viewport dimensions.
GLsizei viewport_max_width;
GLsizei viewport_max_height;

// The currently bound array buffer. If this is 0 it is illegal to call
// glVertexAttribPointer.
BufferManager::BufferInfo::Ref bound_array_buffer;

// Which textures are bound to texture units through glActiveTexture.
scoped_array<TextureUnit> texture_units;
std::vector<TextureUnit> texture_units;

// Class that manages vertex attribs.
VertexAttribManager::Ref vertex_attrib_manager;
Expand Down
4 changes: 2 additions & 2 deletions gpu/command_buffer/service/context_state_impl_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void ContextState::Initialize() {
viewport_height = 1;
}

void ContextState::InitCapabilities() {
void ContextState::InitCapabilities() const {
EnableDisable(GL_BLEND, enable_flags.blend);
EnableDisable(GL_CULL_FACE, enable_flags.cull_face);
EnableDisable(GL_DEPTH_TEST, enable_flags.depth_test);
Expand All @@ -91,7 +91,7 @@ void ContextState::InitCapabilities() {
EnableDisable(GL_STENCIL_TEST, enable_flags.stencil_test);
}

void ContextState::InitState() {
void ContextState::InitState() const {
glBlendColor(
blend_color_red, blend_color_green, blend_color_blue, blend_color_alpha);
glBlendEquationSeparate(blend_equation_rgb, blend_equation_alpha);
Expand Down
79 changes: 79 additions & 0 deletions gpu/command_buffer/service/gl_context_virtual.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) 2012 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 "gpu/command_buffer/service/gl_context_virtual.h"

#include "gpu/command_buffer/service/gl_state_restorer_impl.h"
#include "ui/gl/gl_surface.h"

namespace gpu {

GLContextVirtual::GLContextVirtual(
gfx::GLShareGroup* share_group,
gfx::GLContext* shared_context,
gles2::GLES2Decoder* decoder)
: GLContext(share_group),
shared_context_(shared_context),
display_(NULL),
state_restorer_(new GLStateRestorerImpl(decoder)) {
shared_context_->SetupForVirtualization();
}

gfx::Display* GLContextVirtual::display() {
return display_;
}

bool GLContextVirtual::Initialize(
gfx::GLSurface* compatible_surface, gfx::GpuPreference gpu_preference) {
display_ = static_cast<gfx::Display*>(compatible_surface->GetDisplay());

return true;
}

void GLContextVirtual::Destroy() {
}

bool GLContextVirtual::MakeCurrent(gfx::GLSurface* surface) {
shared_context_->MakeVirtuallyCurrent(this, surface);
return true;
}

void GLContextVirtual::ReleaseCurrent(gfx::GLSurface* surface) {
shared_context_ = NULL;
display_ = NULL;
}

bool GLContextVirtual::IsCurrent(gfx::GLSurface* surface) {
return true;
}

void* GLContextVirtual::GetHandle() {
return NULL;
}

gfx::GLStateRestorer* GLContextVirtual::GetGLStateRestorer() {
return state_restorer_.get();
}

void GLContextVirtual::SetSwapInterval(int interval) {
shared_context_->SetSwapInterval(interval);
}

std::string GLContextVirtual::GetExtensions() {
return shared_context_->GetExtensions();
}

bool GLContextVirtual::GetTotalGpuMemory(size_t* bytes) {
return shared_context_->GetTotalGpuMemory(bytes);
}

bool GLContextVirtual::WasAllocatedUsingRobustnessExtension() {
return shared_context_->WasAllocatedUsingRobustnessExtension();
}

GLContextVirtual::~GLContextVirtual() {
Destroy();
}

} // namespace gpu
62 changes: 62 additions & 0 deletions gpu/command_buffer/service/gl_context_virtual.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) 2012 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.

#ifndef GPU_COMMAND_BUFFER_SERVICE_GL_CONTEXT_VIRTUAL_H_
#define GPU_COMMAND_BUFFER_SERVICE_GL_CONTEXT_VIRTUAL_H_

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "gpu/gpu_export.h"
#include "ui/gl/gl_context.h"

namespace gfx {
class Display;
class GLSurface;
class GLStateRestorer;
}

namespace gpu {
namespace gles2 {
class GLES2Decoder;
}

// Encapsulates a virtual OpenGL context.
class GPU_EXPORT GLContextVirtual : public gfx::GLContext {
public:
GLContextVirtual(
gfx::GLShareGroup* share_group,
gfx::GLContext* shared_context,
gles2::GLES2Decoder* decoder);

gfx::Display* display();

// Implement GLContext.
virtual bool Initialize(
gfx::GLSurface* compatible_surface,
gfx::GpuPreference gpu_preference) OVERRIDE;
virtual void Destroy() OVERRIDE;
virtual bool MakeCurrent(gfx::GLSurface* surface) OVERRIDE;
virtual void ReleaseCurrent(gfx::GLSurface* surface) OVERRIDE;
virtual bool IsCurrent(gfx::GLSurface* surface) OVERRIDE;
virtual void* GetHandle() OVERRIDE;
virtual gfx::GLStateRestorer* GetGLStateRestorer() OVERRIDE;
virtual void SetSwapInterval(int interval) OVERRIDE;
virtual std::string GetExtensions() OVERRIDE;
virtual bool GetTotalGpuMemory(size_t* bytes) OVERRIDE;
virtual bool WasAllocatedUsingRobustnessExtension() OVERRIDE;

protected:
virtual ~GLContextVirtual();

private:
gfx::GLContext* shared_context_;
gfx::Display* display_;
scoped_ptr<gfx::GLStateRestorer> state_restorer_;

DISALLOW_COPY_AND_ASSIGN(GLContextVirtual);
};

} // namespace gpu

#endif // GPU_COMMAND_BUFFER_SERVICE_GL_CONTEXT_VIRTUAL_H_
24 changes: 24 additions & 0 deletions gpu/command_buffer/service/gl_state_restorer_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2012 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 "gpu/command_buffer/service/gl_state_restorer_impl.h"

#include "gpu/command_buffer/service/gles2_cmd_decoder.h"

namespace gpu {

GLStateRestorerImpl::GLStateRestorerImpl(gles2::GLES2Decoder* decoder)
: decoder_(decoder) {
}

GLStateRestorerImpl::~GLStateRestorerImpl() {
}

void GLStateRestorerImpl::RestoreState() {
decoder_->RestoreState();
}

} // namespace gpu


36 changes: 36 additions & 0 deletions gpu/command_buffer/service/gl_state_restorer_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2012 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.

// This file contains the GLStateRestorerImpl class.

#ifndef GPU_COMMAND_BUFFER_SERVICE_GL_STATE_RESTORER_IMPL_H_
#define GPU_COMMAND_BUFFER_SERVICE_GL_STATE_RESTORER_IMPL_H_

#include "base/compiler_specific.h"
#include "gpu/gpu_export.h"
#include "ui/gl/gl_state_restorer.h"

namespace gpu {
namespace gles2 {
class GLES2Decoder;
}

// This class implements a GLStateRestorer that forwards to a GLES2Decoder.
class GPU_EXPORT GLStateRestorerImpl : public gfx::GLStateRestorer {
public:
explicit GLStateRestorerImpl(gles2::GLES2Decoder* decoder);
virtual ~GLStateRestorerImpl();

virtual void RestoreState() OVERRIDE;

private:
gles2::GLES2Decoder* decoder_;

DISALLOW_COPY_AND_ASSIGN(GLStateRestorerImpl);
};

} // namespace gpu

#endif // GPU_COMMAND_BUFFER_SERVICE_GL_STATE_RESTORER_IMPL_H_

Loading

0 comments on commit 1868a34

Please sign in to comment.