diff options
author | petersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-21 22:54:30 +0000 |
---|---|---|
committer | petersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-21 22:54:30 +0000 |
commit | 66547160c1f2646c9d3f1ec363d41ae56e62f29f (patch) | |
tree | 9bd79ae8a734a1a6e52113e35244db9ab1d5fa50 /o3d | |
parent | 8811c0afff04ff12ba34908469cf90daa0724276 (diff) | |
download | chromium_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.scons | 2 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/gapi_gl.cc | 3 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/gapi_gl.h | 41 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/geometry_gl.cc | 2 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/geometry_gl.h | 2 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/render_surface_gl.cc | 261 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/render_surface_gl.h | 117 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/sampler_gl.cc | 3 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/texture_gl.cc | 143 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/texture_gl.h | 75 |
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); |