summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-21 22:54:30 +0000
committerpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-21 22:54:30 +0000
commit66547160c1f2646c9d3f1ec363d41ae56e62f29f (patch)
tree9bd79ae8a734a1a6e52113e35244db9ab1d5fa50 /o3d
parent8811c0afff04ff12ba34908469cf90daa0724276 (diff)
downloadchromium_src-66547160c1f2646c9d3f1ec363d41ae56e62f29f.zip
chromium_src-66547160c1f2646c9d3f1ec363d41ae56e62f29f.tar.gz
chromium_src-66547160c1f2646c9d3f1ec363d41ae56e62f29f.tar.bz2
Added render surfaces in command buffer service opengl version.
Review URL: http://codereview.chromium.org/211020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26760 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/command_buffer/service/build.scons2
-rw-r--r--o3d/command_buffer/service/cross/gl/gapi_gl.cc3
-rw-r--r--o3d/command_buffer/service/cross/gl/gapi_gl.h41
-rw-r--r--o3d/command_buffer/service/cross/gl/geometry_gl.cc2
-rw-r--r--o3d/command_buffer/service/cross/gl/geometry_gl.h2
-rw-r--r--o3d/command_buffer/service/cross/gl/render_surface_gl.cc261
-rw-r--r--o3d/command_buffer/service/cross/gl/render_surface_gl.h117
-rw-r--r--o3d/command_buffer/service/cross/gl/sampler_gl.cc3
-rw-r--r--o3d/command_buffer/service/cross/gl/texture_gl.cc143
-rw-r--r--o3d/command_buffer/service/cross/gl/texture_gl.h75
10 files changed, 601 insertions, 48 deletions
diff --git a/o3d/command_buffer/service/build.scons b/o3d/command_buffer/service/build.scons
index 9c29f77..3a0a199 100644
--- a/o3d/command_buffer/service/build.scons
+++ b/o3d/command_buffer/service/build.scons
@@ -100,6 +100,7 @@ if env['TARGET_PLATFORM'] == 'WINDOWS':
INPUTS += ['cross/gl/effect_gl.cc',
'cross/gl/gapi_gl.cc',
'cross/gl/geometry_gl.cc',
+ 'cross/gl/render_surface_gl.cc',
'cross/gl/sampler_gl.cc',
'cross/gl/states_gl.cc',
'cross/gl/texture_gl.cc']
@@ -110,6 +111,7 @@ elif env['TARGET_PLATFORM'] == 'LINUX':
INPUTS += ['cross/gl/effect_gl.cc',
'cross/gl/gapi_gl.cc',
'cross/gl/geometry_gl.cc',
+ 'cross/gl/render_surface_gl.cc',
'cross/gl/sampler_gl.cc',
'cross/gl/states_gl.cc',
'cross/gl/texture_gl.cc',
diff --git a/o3d/command_buffer/service/cross/gl/gapi_gl.cc b/o3d/command_buffer/service/cross/gl/gapi_gl.cc
index 9f3873f..fd5c6d3 100644
--- a/o3d/command_buffer/service/cross/gl/gapi_gl.cc
+++ b/o3d/command_buffer/service/cross/gl/gapi_gl.cc
@@ -293,6 +293,9 @@ bool GAPIGL::InitCommon() {
glGetIntegerv(GL_VIEWPORT, viewport);
SetViewport(viewport[0], viewport[1], viewport[2], viewport[3], 0.f, 1.f);
CHECK_GL_ERROR();
+
+ ::glGenFramebuffersEXT(1, &render_surface_framebuffer_);
+ CHECK_GL_ERROR();
return true;
}
diff --git a/o3d/command_buffer/service/cross/gl/gapi_gl.h b/o3d/command_buffer/service/cross/gl/gapi_gl.h
index 5043108..d4602c2 100644
--- a/o3d/command_buffer/service/cross/gl/gapi_gl.h
+++ b/o3d/command_buffer/service/cross/gl/gapi_gl.h
@@ -41,6 +41,7 @@
#include "command_buffer/service/cross/gl/gl_utils.h"
#include "command_buffer/service/cross/gl/effect_gl.h"
#include "command_buffer/service/cross/gl/geometry_gl.h"
+#include "command_buffer/service/cross/gl/render_surface_gl.h"
#include "command_buffer/service/cross/gl/sampler_gl.h"
#include "command_buffer/service/cross/gl/texture_gl.h"
@@ -226,7 +227,8 @@ class GAPIGL : public GAPIInterface {
unsigned int height,
unsigned int levels,
texture::Format format,
- unsigned int flags);
+ unsigned int flags,
+ bool enable_render_surfaces);
// Implements the CreateTexture3D function for GL.
virtual ParseError CreateTexture3D(ResourceID id,
@@ -235,14 +237,16 @@ class GAPIGL : public GAPIInterface {
unsigned int depth,
unsigned int levels,
texture::Format format,
- unsigned int flags);
+ unsigned int flags,
+ bool enable_render_surfaces);
// Implements the CreateTextureCube function for GL.
virtual ParseError CreateTextureCube(ResourceID id,
unsigned int side,
unsigned int levels,
texture::Format format,
- unsigned int flags);
+ unsigned int flags,
+ bool enable_render_surfaces);
// Implements the SetTextureData function for GL.
virtual ParseError SetTextureData(ResourceID id,
@@ -356,6 +360,32 @@ class GAPIGL : public GAPIInterface {
// Implements the SetBlendingColor function for GL.
virtual void SetBlendingColor(const RGBA &color);
+ // Implements the CreateRenderSurface function for GL.
+ virtual ParseError CreateRenderSurface(ResourceID id,
+ unsigned int width,
+ unsigned int height,
+ unsigned int mip_level,
+ unsigned int side,
+ ResourceID texture_id);
+
+ // Implements the DestroyRenderSurface function for GL.
+ virtual ParseError DestroyRenderSurface(ResourceID id);
+
+ // Implements the CreateDepthSurface function for GL.
+ virtual ParseError CreateDepthSurface(ResourceID id,
+ unsigned int width,
+ unsigned int height);
+
+ // Implements the DestroyDepthSurface function for GL.
+ virtual ParseError DestroyDepthSurface(ResourceID id);
+
+ // Implements the SetRenderSurface function for GL.
+ virtual ParseError SetRenderSurface(ResourceID render_surface_id,
+ ResourceID depth_stencil_id);
+
+ // Implements the SetBackSurfaces function for GL.
+ virtual void SetBackSurfaces();
+
// Gets a vertex buffer by resource ID.
VertexBufferGL *GetVertexBuffer(ResourceID id) {
return vertex_buffers_.Get(id);
@@ -407,6 +437,9 @@ class GAPIGL : public GAPIInterface {
ResourceID current_effect_id_;
bool validate_effect_;
EffectGL *current_effect_;
+ ResourceID current_surface_id_;
+ ResourceID current_depth_surface_id_;
+ GLuint render_surface_framebuffer_;
ResourceMap<VertexBufferGL> vertex_buffers_;
ResourceMap<IndexBufferGL> index_buffers_;
@@ -415,6 +448,8 @@ class GAPIGL : public GAPIInterface {
ResourceMap<EffectParamGL> effect_params_;
ResourceMap<TextureGL> textures_;
ResourceMap<SamplerGL> samplers_;
+ ResourceMap<RenderSurfaceGL> render_surfaces_;
+ ResourceMap<RenderDepthStencilSurfaceGL> depth_surfaces_;
};
} // namespace command_buffer
diff --git a/o3d/command_buffer/service/cross/gl/geometry_gl.cc b/o3d/command_buffer/service/cross/gl/geometry_gl.cc
index be5bf1a1..c6e1dc8 100644
--- a/o3d/command_buffer/service/cross/gl/geometry_gl.cc
+++ b/o3d/command_buffer/service/cross/gl/geometry_gl.cc
@@ -249,7 +249,7 @@ inline unsigned int GetAttribIndex(vertex_struct::Semantic semantic,
return 8 + semantic_index;
default:
DLOG(FATAL) << "Not reached.";
- break;
+ return 0;
}
}
diff --git a/o3d/command_buffer/service/cross/gl/geometry_gl.h b/o3d/command_buffer/service/cross/gl/geometry_gl.h
index 580f14d..d83e7b5 100644
--- a/o3d/command_buffer/service/cross/gl/geometry_gl.h
+++ b/o3d/command_buffer/service/cross/gl/geometry_gl.h
@@ -126,7 +126,7 @@ class VertexStructGL : public VertexStruct {
GLenum type;
GLboolean normalized;
GLsizei stride;
- GLintptr offset;
+ ptrdiff_t offset;
};
// Compiles the vertex declaration into the attribute array.
diff --git a/o3d/command_buffer/service/cross/gl/render_surface_gl.cc b/o3d/command_buffer/service/cross/gl/render_surface_gl.cc
new file mode 100644
index 0000000..5c9b752
--- /dev/null
+++ b/o3d/command_buffer/service/cross/gl/render_surface_gl.cc
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+// This file implements the OpenGL versions of the render surface resources,
+// as well as the related GAPIGL function implementations.
+
+#include "command_buffer/service/cross/gl/gapi_gl.h"
+#include "command_buffer/service/cross/gl/render_surface_gl.h"
+
+
+namespace o3d {
+namespace command_buffer {
+
+RenderSurfaceGL::RenderSurfaceGL(int width,
+ int height,
+ int mip_level,
+ int side,
+ TextureGL *texture)
+ : width_(width), height_(height), mip_level_(mip_level), texture_(texture) {
+}
+
+RenderSurfaceGL* RenderSurfaceGL::Create(int width,
+ int height,
+ int mip_level,
+ int side,
+ TextureGL *texture) {
+ DCHECK_GT(width, 0);
+ DCHECK_GT(height, 0);
+ DCHECK_GE(mip_level, 0);
+ DCHECK(texture);
+
+ RenderSurfaceGL* render_surface =
+ new RenderSurfaceGL(width, height, mip_level, side, texture);
+ return render_surface;
+}
+
+RenderDepthStencilSurfaceGL::RenderDepthStencilSurfaceGL(
+ int width,
+ int height)
+ : width_(width), height_(height) {
+ DCHECK_GT(width, 0);
+ DCHECK_GT(height, 0);
+
+ // If packed depth stencil is supported, create only one buffer for both
+ // depth and stencil.
+ if (GLEW_EXT_packed_depth_stencil) {
+ glGenRenderbuffersEXT(1, render_buffers_);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[0]);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
+ GL_DEPTH24_STENCIL8_EXT,
+ width,
+ height);
+ CHECK_GL_ERROR();
+ render_buffers_[1] = render_buffers_[0];
+ } else {
+ glGenRenderbuffersEXT(2, render_buffers_);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[0]);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
+ GL_DEPTH_COMPONENT24,
+ width,
+ height);
+ CHECK_GL_ERROR();
+
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[1]);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
+ GL_STENCIL_INDEX8_EXT,
+ width,
+ height);
+ CHECK_GL_ERROR();
+ }
+}
+
+RenderDepthStencilSurfaceGL* RenderDepthStencilSurfaceGL::Create(
+ int width,
+ int height) {
+ DCHECK_GT(width, 0);
+ DCHECK_GT(height, 0);
+
+ return new RenderDepthStencilSurfaceGL(height, width);
+}
+
+// Copies the data from a texture resource.
+BufferSyncInterface::ParseError GAPIGL::CreateRenderSurface(
+ ResourceID id,
+ unsigned int width,
+ unsigned int height,
+ unsigned int mip_level,
+ unsigned int side,
+ ResourceID texture_id) {
+ if (id == current_surface_id_) {
+ // This will delete the current surface which would be bad.
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ }
+ TextureGL *texture = textures_.Get(texture_id);
+ if (!texture->render_surfaces_enabled()) {
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ } else {
+ RenderSurfaceGL* render_surface = RenderSurfaceGL::Create(width,
+ height,
+ mip_level,
+ side,
+ texture);
+ if (render_surface == NULL) {
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ }
+ render_surfaces_.Assign(id, render_surface);
+ }
+ return BufferSyncInterface::PARSE_NO_ERROR;
+}
+
+BufferSyncInterface::ParseError GAPIGL::DestroyRenderSurface(ResourceID id) {
+ if (id == current_surface_id_) {
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ }
+ return render_surfaces_.Destroy(id) ?
+ BufferSyncInterface::PARSE_NO_ERROR :
+ BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+}
+
+BufferSyncInterface::ParseError GAPIGL::CreateDepthSurface(
+ ResourceID id,
+ unsigned int width,
+ unsigned int height) {
+ if (id == current_depth_surface_id_) {
+ // This will delete the current surface which would be bad.
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ }
+ RenderDepthStencilSurfaceGL* depth_surface =
+ RenderDepthStencilSurfaceGL::Create(width, height);
+ if (depth_surface == NULL) {
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ }
+ depth_surfaces_.Assign(id, depth_surface);
+ return BufferSyncInterface::PARSE_NO_ERROR;
+}
+
+BufferSyncInterface::ParseError GAPIGL::DestroyDepthSurface(ResourceID id) {
+ if (id == current_depth_surface_id_) {
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ }
+ return depth_surfaces_.Destroy(id) ?
+ BufferSyncInterface::PARSE_NO_ERROR :
+ BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+}
+
+void ResetBoundAttachments() {
+#ifdef _DEBUG
+ GLint bound_framebuffer;
+ ::glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_framebuffer);
+ DCHECK(bound_framebuffer != 0);
+#endif
+
+ // Reset the bound attachments to the current framebuffer object.
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_RENDERBUFFER_EXT,
+ 0);
+
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT,
+ 0);
+
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_STENCIL_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT,
+ 0);
+
+ CHECK_GL_ERROR();
+}
+
+bool BindDepthStencilBuffer(const RenderDepthStencilSurfaceGL* gl_surface) {
+ // Bind both the depth and stencil attachments.
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT,
+ gl_surface->depth_buffer());
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_STENCIL_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT,
+ gl_surface->stencil_buffer());
+
+ // Check for errors.
+ GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) {
+ return false;
+ }
+
+ CHECK_GL_ERROR();
+ return true;
+}
+
+BufferSyncInterface::ParseError GAPIGL::SetRenderSurface(
+ ResourceID render_surface_id,
+ ResourceID depth_stencil_id) {
+ if (render_surfaces_.Get(render_surface_id) == NULL &&
+ depth_surfaces_.Get(depth_stencil_id) == NULL) {
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ }
+
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER, render_surface_framebuffer_);
+ ResetBoundAttachments();
+
+ RenderSurfaceGL* render_surface = render_surfaces_.Get(render_surface_id);
+ RenderDepthStencilSurfaceGL* depth_surface =
+ depth_surfaces_.Get(render_surface_id);
+
+ if (!render_surface->texture()->
+ InstallFrameBufferObjects(render_surface) ||
+ !BindDepthStencilBuffer(depth_surface)) {
+ return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
+ }
+
+ // RenderSurface rendering is performed with an inverted Y, so the front
+ // face winding must be changed to clock-wise. See comments for
+ // UpdateHelperConstant.
+ glFrontFace(GL_CW);
+
+ current_surface_id_ = render_surface_id;
+ current_depth_surface_id_ = depth_stencil_id;
+ return BufferSyncInterface::PARSE_NO_ERROR;
+}
+
+void GAPIGL::SetBackSurfaces() {
+ // Bind the default context, and restore the default front-face winding.
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
+ glFrontFace(GL_CCW);
+}
+
+} // namespace command_buffer
+} // namespace o3d
+
diff --git a/o3d/command_buffer/service/cross/gl/render_surface_gl.h b/o3d/command_buffer/service/cross/gl/render_surface_gl.h
new file mode 100644
index 0000000..9bdb535
--- /dev/null
+++ b/o3d/command_buffer/service/cross/gl/render_surface_gl.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef O3D_COMMAND_BUFFER_SERVICE_CROSS_GL_RENDER_SURFACE_GL_H__
+#define O3D_COMMAND_BUFFER_SERVICE_CROSS_GL_RENDER_SURFACE_GL_H__
+
+// This file contains the definition of the OpenGL versions of
+// render surface-related resource classes.
+
+#include "command_buffer/service/cross/gl/texture_gl.h"
+#include "command_buffer/service/cross/resource.h"
+
+namespace o3d {
+namespace command_buffer {
+
+class RenderSurfaceGL : public RenderSurface {
+ public:
+ RenderSurfaceGL(int width,
+ int height,
+ int mip_level,
+ int side,
+ TextureGL *texture);
+ virtual ~RenderSurfaceGL() {}
+
+ static RenderSurfaceGL* Create(int width,
+ int height,
+ int mip_level,
+ int side,
+ TextureGL *texture);
+ TextureGL* texture() {
+ return texture_;
+ }
+
+ int width() {
+ return width_;
+ }
+
+ int height() {
+ return height_;
+ }
+
+ int mip_level() {
+ return mip_level_;
+ }
+
+ int side() {
+ return side_;
+ }
+ private:
+ unsigned int width_;
+ unsigned int height_;
+ unsigned int mip_level_;
+ unsigned int side_;
+ TextureGL* texture_;
+ DISALLOW_COPY_AND_ASSIGN(RenderSurfaceGL);
+};
+
+class RenderDepthStencilSurfaceGL : public RenderDepthStencilSurface {
+ public:
+ RenderDepthStencilSurfaceGL(int width,
+ int height);
+ virtual ~RenderDepthStencilSurfaceGL() {}
+
+ static RenderDepthStencilSurfaceGL* Create(
+ int width,
+ int height);
+
+ GLuint depth_buffer() const {
+ return render_buffers_[0];
+ }
+
+ GLuint stencil_buffer() const {
+ return render_buffers_[1];
+ }
+
+ private:
+ // Handles to the depth and stencil render-buffers, respectively.
+ GLuint render_buffers_[2];
+ unsigned int width_;
+ unsigned int height_;
+ DISALLOW_COPY_AND_ASSIGN(RenderDepthStencilSurfaceGL);
+};
+
+} // namespace command_buffer
+} // namespace o3d
+
+#endif // O3D_COMMAND_BUFFER_SERVICE_WIN_GL_RENDER_SURFACE_GL_H__
+
diff --git a/o3d/command_buffer/service/cross/gl/sampler_gl.cc b/o3d/command_buffer/service/cross/gl/sampler_gl.cc
index 2262e6c..cbd1d1b 100644
--- a/o3d/command_buffer/service/cross/gl/sampler_gl.cc
+++ b/o3d/command_buffer/service/cross/gl/sampler_gl.cc
@@ -105,6 +105,9 @@ GLenum GLTextureTarget(texture::Type type) {
return GL_TEXTURE_3D;
case texture::TEXTURE_CUBE:
return GL_TEXTURE_CUBE_MAP;
+ default:
+ DLOG(FATAL) << "Not Reached";
+ return GL_TEXTURE_2D;
}
}
diff --git a/o3d/command_buffer/service/cross/gl/texture_gl.cc b/o3d/command_buffer/service/cross/gl/texture_gl.cc
index 9155dcc..8280b77 100644
--- a/o3d/command_buffer/service/cross/gl/texture_gl.cc
+++ b/o3d/command_buffer/service/cross/gl/texture_gl.cc
@@ -207,7 +207,8 @@ Texture2DGL *Texture2DGL::Create(unsigned int width,
unsigned int height,
unsigned int levels,
texture::Format format,
- unsigned int flags) {
+ unsigned int flags,
+ bool enable_render_surfaces) {
DCHECK_GT(width, 0);
DCHECK_GT(height, 0);
DCHECK_GT(levels, 0);
@@ -223,18 +224,19 @@ Texture2DGL *Texture2DGL::Create(unsigned int width,
// glCompressedTexImage2D does't accept NULL as a parameter, so we need
// to pass in some data.
scoped_array<unsigned char> buffer;
- if (!gl_format) {
- MipLevelInfo mip_info;
- MakeMipLevelInfo(&mip_info, format, width, height, 1, 0);
- unsigned int size = GetMipLevelSize(mip_info);
- buffer.reset(new unsigned char[size]);
- }
+ MipLevelInfo mip_info;
+ MakeMipLevelInfo(&mip_info, format, width, height, 1, 0);
+ unsigned int size = GetMipLevelSize(mip_info);
+ buffer.reset(new unsigned char[size]);
+ memset(buffer.get(), 0, size);
+
unsigned int mip_width = width;
unsigned int mip_height = height;
+
for (unsigned int i = 0; i < levels; ++i) {
if (gl_format) {
glTexImage2D(GL_TEXTURE_2D, i, gl_internal_format, mip_width, mip_height,
- 0, gl_format, gl_type, NULL);
+ 0, gl_format, gl_type, buffer.get());
} else {
MipLevelInfo mip_info;
MakeMipLevelInfo(&mip_info, format, width, height, 1, i);
@@ -245,7 +247,8 @@ Texture2DGL *Texture2DGL::Create(unsigned int width,
mip_width = std::max(1U, mip_width >> 1);
mip_height = std::max(1U, mip_height >> 1);
}
- return new Texture2DGL(levels, format, flags, width, height, gl_texture);
+ return new Texture2DGL(
+ levels, format, enable_render_surfaces, flags, width, height, gl_texture);
}
// Sets data into a 2D texture resource.
@@ -313,12 +316,37 @@ bool Texture2DGL::GetData(const Volume& volume,
return true;
}
+bool Texture2DGL::CreateRenderSurface(int width,
+ int height,
+ int mip_level,
+ int side) {
+ return false;
+}
+
+bool Texture2DGL::InstallFrameBufferObjects(
+ RenderSurfaceGL *gl_surface) {
+ ::glFramebufferTexture2DEXT(
+ GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D,
+ gl_texture_,
+ gl_surface->mip_level());
+
+ GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) {
+ return false;
+ }
+
+ return true;
+}
+
Texture3DGL *Texture3DGL::Create(unsigned int width,
unsigned int height,
unsigned int depth,
unsigned int levels,
texture::Format format,
- unsigned int flags) {
+ unsigned int flags,
+ bool enable_render_surfaces) {
DCHECK_GT(width, 0);
DCHECK_GT(height, 0);
DCHECK_GT(depth, 0);
@@ -335,19 +363,19 @@ Texture3DGL *Texture3DGL::Create(unsigned int width,
// glCompressedTexImage3D does't accept NULL as a parameter, so we need
// to pass in some data.
scoped_array<unsigned char> buffer;
- if (!gl_format) {
- MipLevelInfo mip_info;
- MakeMipLevelInfo(&mip_info, format, width, height, depth, 0);
- unsigned int size = GetMipLevelSize(mip_info);
- buffer.reset(new unsigned char[size]);
- }
+ MipLevelInfo mip_info;
+ MakeMipLevelInfo(&mip_info, format, width, height, depth, 0);
+ unsigned int size = GetMipLevelSize(mip_info);
+ buffer.reset(new unsigned char[size]);
+ memset(buffer.get(), 0, size);
+
unsigned int mip_width = width;
unsigned int mip_height = height;
unsigned int mip_depth = depth;
for (unsigned int i = 0; i < levels; ++i) {
if (gl_format) {
glTexImage3D(GL_TEXTURE_3D, i, gl_internal_format, mip_width, mip_height,
- mip_depth, 0, gl_format, gl_type, NULL);
+ mip_depth, 0, gl_format, gl_type, buffer.get());
} else {
MipLevelInfo mip_info;
MakeMipLevelInfo(&mip_info, format, width, height, depth, i);
@@ -359,8 +387,8 @@ Texture3DGL *Texture3DGL::Create(unsigned int width,
mip_height = std::max(1U, mip_height >> 1);
mip_depth = std::max(1U, mip_depth >> 1);
}
- return new Texture3DGL(levels, format, flags, width, height, depth,
- gl_texture);
+ return new Texture3DGL(levels, format, enable_render_surfaces, flags, width,
+ height, depth, gl_texture);
}
bool Texture3DGL::SetData(const Volume& volume,
@@ -429,10 +457,23 @@ bool Texture3DGL::GetData(const Volume& volume,
return true;
}
+bool Texture3DGL::CreateRenderSurface(int width,
+ int height,
+ int mip_level,
+ int side) {
+ return false;
+}
+
+bool Texture3DGL::InstallFrameBufferObjects(
+ RenderSurfaceGL *gl_surface) {
+ return false;
+}
+
TextureCubeGL *TextureCubeGL::Create(unsigned int side,
unsigned int levels,
texture::Format format,
- unsigned int flags) {
+ unsigned int flags,
+ bool enable_render_surfaces) {
DCHECK_GT(side, 0);
DCHECK_GT(levels, 0);
GLenum gl_internal_format = 0;
@@ -448,19 +489,19 @@ TextureCubeGL *TextureCubeGL::Create(unsigned int side,
// glCompressedTexImage2D does't accept NULL as a parameter, so we need
// to pass in some data.
scoped_array<unsigned char> buffer;
- if (!gl_format) {
- MipLevelInfo mip_info;
- MakeMipLevelInfo(&mip_info, format, side, side, 1, 0);
- unsigned int size = GetMipLevelSize(mip_info);
- buffer.reset(new unsigned char[size]);
- }
+ MipLevelInfo mip_info;
+ MakeMipLevelInfo(&mip_info, format, side, side, 1, 0);
+ unsigned int size = GetMipLevelSize(mip_info);
+ buffer.reset(new unsigned char[size]);
+ memset(buffer.get(), 0, size);
+
unsigned int mip_side = side;
for (unsigned int i = 0; i < levels; ++i) {
if (gl_format) {
for (unsigned int face = 0; face < 6; ++face) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i,
gl_internal_format, mip_side, mip_side,
- 0, gl_format, gl_type, NULL);
+ 0, gl_format, gl_type, buffer.get());
}
} else {
MipLevelInfo mip_info;
@@ -474,7 +515,8 @@ TextureCubeGL *TextureCubeGL::Create(unsigned int side,
}
mip_side = std::max(1U, mip_side >> 1);
}
- return new TextureCubeGL(levels, format, flags, side, gl_texture);
+ return new TextureCubeGL(
+ levels, format, enable_render_surfaces, flags, side, gl_texture);
}
// Check that GL_TEXTURE_CUBE_MAP_POSITIVE_X + face yields the correct GLenum.
@@ -557,6 +599,31 @@ bool TextureCubeGL::GetData(const Volume& volume,
return true;
}
+bool TextureCubeGL::CreateRenderSurface(int width,
+ int height,
+ int mip_level,
+ int side) {
+ return false;
+}
+
+bool TextureCubeGL::InstallFrameBufferObjects(
+ RenderSurfaceGL *gl_surface) {
+ ::glFramebufferTexture2DEXT(
+ GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ gl_surface->side(),
+ gl_texture_,
+ gl_surface->mip_level());
+
+ GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) {
+ return false;
+ }
+
+ return true;
+}
+
+
// GAPIGL functions.
// Destroys a texture resource.
@@ -575,9 +642,10 @@ BufferSyncInterface::ParseError GAPIGL::CreateTexture2D(
unsigned int height,
unsigned int levels,
texture::Format format,
- unsigned int flags) {
- Texture2DGL *texture = Texture2DGL::Create(width, height, levels, format,
- flags);
+ unsigned int flags,
+ bool enable_render_surfaces) {
+ Texture2DGL *texture = Texture2DGL::Create(
+ width, height, levels, format, flags, enable_render_surfaces);
if (!texture) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
// Dirty effect, because this texture id may be used.
DirtyEffect();
@@ -593,9 +661,10 @@ BufferSyncInterface::ParseError GAPIGL::CreateTexture3D(
unsigned int depth,
unsigned int levels,
texture::Format format,
- unsigned int flags) {
- Texture3DGL *texture = Texture3DGL::Create(width, height, depth, levels,
- format, flags);
+ unsigned int flags,
+ bool enable_render_surfaces) {
+ Texture3DGL *texture = Texture3DGL::Create(
+ width, height, depth, levels, format, flags, enable_render_surfaces);
if (!texture) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
// Dirty effect, because this texture id may be used.
DirtyEffect();
@@ -609,8 +678,10 @@ BufferSyncInterface::ParseError GAPIGL::CreateTextureCube(
unsigned int side,
unsigned int levels,
texture::Format format,
- unsigned int flags) {
- TextureCubeGL *texture = TextureCubeGL::Create(side, levels, format, flags);
+ unsigned int flags,
+ bool enable_render_surfaces) {
+ TextureCubeGL *texture = TextureCubeGL::Create(
+ side, levels, format, flags, enable_render_surfaces);
if (!texture) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
// Dirty effect, because this texture id may be used.
DirtyEffect();
diff --git a/o3d/command_buffer/service/cross/gl/texture_gl.h b/o3d/command_buffer/service/cross/gl/texture_gl.h
index bc6d9c2..db7d9ed 100644
--- a/o3d/command_buffer/service/cross/gl/texture_gl.h
+++ b/o3d/command_buffer/service/cross/gl/texture_gl.h
@@ -44,6 +44,9 @@
namespace o3d {
namespace command_buffer {
+class RenderDepthStencilSurfaceGL;
+class RenderSurfaceGL;
+
// The base class for a GL texture resource, providing access to the base GL
// texture that can be assigned to an effect parameter or a sampler unit.
class TextureGL : public Texture {
@@ -51,9 +54,10 @@ class TextureGL : public Texture {
TextureGL(texture::Type type,
unsigned int levels,
texture::Format format,
+ bool enable_render_surfaces,
unsigned int flags,
GLuint gl_texture)
- : Texture(type, levels, format, flags),
+ : Texture(type, levels, format, enable_render_surfaces, flags),
gl_texture_(gl_texture) {}
virtual ~TextureGL();
@@ -78,6 +82,15 @@ class TextureGL : public Texture {
unsigned int size,
void *data) = 0;
+ // Creates the render surface, returning false if unable to.
+ virtual bool CreateRenderSurface(int width,
+ int height,
+ int mip_level,
+ int side) = 0;
+
+ virtual bool InstallFrameBufferObjects(
+ RenderSurfaceGL *gl_surface) = 0;
+
protected:
const GLuint gl_texture_;
@@ -90,11 +103,17 @@ class Texture2DGL : public TextureGL {
public:
Texture2DGL(unsigned int levels,
texture::Format format,
+ bool enable_render_surfaces,
unsigned int flags,
unsigned int width,
unsigned int height,
GLuint gl_texture)
- : TextureGL(texture::TEXTURE_2D, levels, format, flags, gl_texture),
+ : TextureGL(texture::TEXTURE_2D,
+ levels,
+ format,
+ enable_render_surfaces,
+ flags,
+ gl_texture),
width_(width),
height_(height) {}
@@ -103,7 +122,8 @@ class Texture2DGL : public TextureGL {
unsigned int height,
unsigned int levels,
texture::Format format,
- unsigned int flags);
+ unsigned int flags,
+ bool enable_render_surfaces);
// Sets data into a 2D texture resource.
virtual bool SetData(const Volume& volume,
@@ -123,6 +143,15 @@ class Texture2DGL : public TextureGL {
unsigned int size,
void *data);
+ // Create a render surface which matches this texture type.
+ virtual bool CreateRenderSurface(int width,
+ int height,
+ int mip_level,
+ int side);
+
+ virtual bool InstallFrameBufferObjects(
+ RenderSurfaceGL *gl_surface);
+
private:
unsigned int width_;
unsigned int height_;
@@ -134,12 +163,18 @@ class Texture3DGL : public TextureGL {
public:
Texture3DGL(unsigned int levels,
texture::Format format,
+ bool enable_render_surfaces,
unsigned int flags,
unsigned int width,
unsigned int height,
unsigned int depth,
GLuint gl_texture)
- : TextureGL(texture::TEXTURE_2D, levels, format, flags, gl_texture),
+ : TextureGL(texture::TEXTURE_2D,
+ levels,
+ format,
+ enable_render_surfaces,
+ flags,
+ gl_texture),
width_(width),
height_(height),
depth_(depth) {}
@@ -150,7 +185,8 @@ class Texture3DGL : public TextureGL {
unsigned int depth,
unsigned int levels,
texture::Format format,
- unsigned int flags);
+ unsigned int flags,
+ bool enable_render_surfaces);
// Sets data into a 3D texture resource.
virtual bool SetData(const Volume& volume,
@@ -170,6 +206,15 @@ class Texture3DGL : public TextureGL {
unsigned int size,
void *data);
+ // Create a render surface which matches this texture type.
+ virtual bool CreateRenderSurface(int width,
+ int height,
+ int mip_level,
+ int side);
+
+ virtual bool InstallFrameBufferObjects(
+ RenderSurfaceGL *gl_surface);
+
private:
unsigned int width_;
unsigned int height_;
@@ -182,17 +227,24 @@ class TextureCubeGL : public TextureGL {
public:
TextureCubeGL(unsigned int levels,
texture::Format format,
+ bool render_surface_enabled,
unsigned int flags,
unsigned int side,
GLuint gl_texture)
- : TextureGL(texture::TEXTURE_CUBE, levels, format, flags, gl_texture),
+ : TextureGL(texture::TEXTURE_CUBE,
+ levels,
+ format,
+ render_surface_enabled,
+ flags,
+ gl_texture),
side_(side) {}
// Creates a cube map texture resource.
static TextureCubeGL *Create(unsigned int side,
unsigned int levels,
texture::Format format,
- unsigned int flags);
+ unsigned int flags,
+ bool enable_render_surfaces);
// Sets data into a cube map texture resource.
virtual bool SetData(const Volume& volume,
@@ -212,6 +264,15 @@ class TextureCubeGL : public TextureGL {
unsigned int size,
void *data);
+ // Create a render surface which matches this texture type.
+ virtual bool CreateRenderSurface(int width,
+ int height,
+ int mip_level,
+ int side);
+
+ virtual bool InstallFrameBufferObjects(
+ RenderSurfaceGL *gl_surface);
+
private:
unsigned int side_;
DISALLOW_COPY_AND_ASSIGN(TextureCubeGL);