summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authordspringer@google.com <dspringer@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-23 18:00:07 +0000
committerdspringer@google.com <dspringer@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-23 18:00:07 +0000
commit1aef9813f6edaead72c9dfe24ccd07ec525c75b3 (patch)
tree9cd13cab509d4e9d32d63b043a0c8132b7033cce /gpu
parentbcc3a0cb7f900dda0b4065055f3539c01f901df2 (diff)
downloadchromium_src-1aef9813f6edaead72c9dfe24ccd07ec525c75b3.zip
chromium_src-1aef9813f6edaead72c9dfe24ccd07ec525c75b3.tar.gz
chromium_src-1aef9813f6edaead72c9dfe24ccd07ec525c75b3.tar.bz2
Add 3D support for the Mac on Leopard (OS X 10.5) and earlier. This CL uses
FBO rendering with glGetTexImage() into a TransportDIB that is then used as a texture for rendering the final image in the render view in the browser. While not optimal, it works and can be optimized later, after the new GPU process work is completed. This CL also enables stencil buffer support on the Mac. All the Pepper3D demos run on the Mac with these changes. BUG=none TEST=3D rendering unit tests. Review URL: http://codereview.chromium.org/647043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39744 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/client/gles2_demo_cc.cc37
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc258
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h11
-rw-r--r--gpu/command_buffer/service/gpu_processor.cc15
-rw-r--r--gpu/command_buffer/service/gpu_processor.h11
5 files changed, 267 insertions, 65 deletions
diff --git a/gpu/command_buffer/client/gles2_demo_cc.cc b/gpu/command_buffer/client/gles2_demo_cc.cc
index c6beff6..8876e6c 100644
--- a/gpu/command_buffer/client/gles2_demo_cc.cc
+++ b/gpu/command_buffer/client/gles2_demo_cc.cc
@@ -5,9 +5,12 @@
// This file is here so other GLES2 related files can have a common set of
// includes where appropriate.
+#include "gpu/command_buffer/client/gles2_demo_cc.h"
+
#include <math.h>
#include <GLES2/gl2.h>
-#include "gpu/command_buffer/client/gles2_demo_cc.h"
+
+#include <string>
namespace {
@@ -19,14 +22,18 @@ GLuint g_vbo = 0;
GLsizei g_texCoordOffset = 0;
int g_angle = 0;
-void CheckGLError() {
- GLenum error = glGetError();
- if (error != GL_NO_ERROR) {
- DLOG(ERROR) << "GL Error: " << error;
+void CheckGLError(const char* func_name, int line_no) {
+#ifndef NDEBUG
+ GLenum error = GL_NO_ERROR;
+ while ((error = glGetError()) != GL_NO_ERROR) {
+ DLOG(ERROR) << "GL Error in " << func_name << " at line " << line_no
+ << ": " << error;
}
+#endif
}
GLuint LoadShader(GLenum type, const char* shaderSrc) {
+ CheckGLError("LoadShader", __LINE__);
GLuint shader = glCreateShader(type);
if (shader == 0) {
return 0;
@@ -70,6 +77,7 @@ void InitShaders() {
" gl_FragColor = texture2D(tex, texCoord);\n"
"}\n";
+ CheckGLError("InitShaders", __LINE__);
GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);
// Create the program object
@@ -127,10 +135,11 @@ void InitShaders() {
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBufferSubData(GL_ARRAY_BUFFER, g_texCoordOffset,
sizeof(texCoords), texCoords);
- CheckGLError();
+ CheckGLError("InitShaders", __LINE__);
}
GLuint CreateCheckerboardTexture() {
+ CheckGLError("CreateCheckerboardTexture", __LINE__);
static unsigned char pixels[] = {
255, 255, 255,
0, 0, 0,
@@ -147,20 +156,24 @@ GLuint CreateCheckerboardTexture() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
pixels);
+ CheckGLError("CreateCheckerboardTexture", __LINE__);
return texture;
}
} // anonymous namespace.
void GLFromCPPInit() {
+ CheckGLError("GLFromCPPInit", __LINE__);
glClearColor(0.f, 0.f, .7f, 1.f);
g_texture = CreateCheckerboardTexture();
InitShaders();
+ CheckGLError("GLFromCPPInit", __LINE__);
}
void GLFromCPPDraw() {
const float kPi = 3.1415926535897932384626433832795f;
+ CheckGLError("GLFromCPPDraw", __LINE__);
// TODO(kbr): base the angle on time rather than on ticks
g_angle = (g_angle + 1) % 360;
// Rotate about the Z axis
@@ -191,10 +204,10 @@ void GLFromCPPDraw() {
// Note: the viewport is automatically set up to cover the entire Canvas.
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
- CheckGLError();
+ CheckGLError("GLFromCPPDraw", __LINE__);
// Use the program object
glUseProgram(g_programObject);
- CheckGLError();
+ CheckGLError("GLFromCPPDraw", __LINE__);
// Set up the model matrix
glUniformMatrix4fv(g_worldMatrixLoc, 1, GL_FALSE, rot_matrix);
@@ -205,14 +218,14 @@ void GLFromCPPDraw() {
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0,
reinterpret_cast<const void*>(g_texCoordOffset));
- CheckGLError();
+ CheckGLError("GLFromCPPDraw", __LINE__);
// Bind the texture to texture unit 0
glBindTexture(GL_TEXTURE_2D, g_texture);
- CheckGLError();
+ CheckGLError("GLFromCPPDraw", __LINE__);
// Point the uniform sampler to texture unit 0
glUniform1i(g_textureLoc, 0);
- CheckGLError();
+ CheckGLError("GLFromCPPDraw", __LINE__);
glDrawArrays(GL_TRIANGLES, 0, 6);
- CheckGLError();
+ CheckGLError("GLFromCPPDraw", __LINE__);
glFlush();
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 58df8de..df18f39 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -6,6 +6,7 @@
#include <stdio.h>
+#include <algorithm>
#include <vector>
#include <string>
#include <map>
@@ -297,7 +298,22 @@ class GLES2DecoderImpl : public GLES2Decoder {
#if defined(OS_MACOSX)
// Overridden from GLES2Decoder.
- virtual uint64 SetWindowSize(int32 width, int32 height);
+
+ // The recommended usage is to call SetWindowSizeForIOSurface() first, and if
+ // that returns 0, try calling SetWindowSizeForTransportDIB(). A return value
+ // of 0 from SetWindowSizeForIOSurface() might mean the IOSurface API is not
+ // available, which is true if you are not running on Max OS X 10.6 or later.
+ // If SetWindowSizeForTransportDIB() also returns a NULL handle, then an
+ // error has occured.
+ virtual uint64 SetWindowSizeForIOSurface(int32 width, int32 height);
+ virtual TransportDIB::Handle SetWindowSizeForTransportDIB(int32 width,
+ int32 height);
+ // |allocator| sends a message to the renderer asking for a new
+ // TransportDIB big enough to hold the rendered bits. The parameters to the
+ // call back are the size of the DIB and the handle (filled in on return).
+ virtual void SetTransportDIBAllocAndFree(
+ Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
+ Callback1<TransportDIB::Id>::Type* deallocator);
#endif
virtual void SetSwapBuffersCallback(Callback0::Type* callback);
@@ -516,6 +532,10 @@ class GLES2DecoderImpl : public GLES2Decoder {
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
return bound_texture_cube_map_;
+ // Note: If we ever support TEXTURE_RECTANGLE as a target, be sure to
+ // track |texture_| with the currently bound TEXTURE_RECTANGLE texture,
+ // because |texture_| is used by the FBO rendering mechanism for readback
+ // to the bits that get sent to the browser.
default:
NOTREACHED();
return 0;
@@ -541,6 +561,20 @@ class GLES2DecoderImpl : public GLES2Decoder {
#undef GLES2_CMD_OP
+#if defined(OS_MACOSX)
+ // Helper function to generate names for the backing texture, render buffers
+ // and FBO. On return, the resulting buffer names can be attached to |fbo_|.
+ // |target| is the target type for the color buffer.
+ void AllocateRenderBuffers(GLenum target, int32 width, int32 height);
+
+ // Helper function to attach the buffers previously allocated by a call to
+ // AllocateRenderBuffers(). On return, |fbo_| can be used for
+ // rendering. |target| must be the same value as used in the call to
+ // AllocateRenderBuffers(). Returns |true| if the resulting framebuffer
+ // object is valid.
+ bool SetupFrameBufferObject(GLenum target);
+#endif
+
// Current GL error bits.
uint32 error_bits_;
@@ -595,16 +629,30 @@ class GLES2DecoderImpl : public GLES2Decoder {
#elif defined(OS_MACOSX)
CGLContextObj gl_context_;
CGLPBufferObj pbuffer_;
+ // Either |io_surface_| or |transport_dib_| is a valid pointer, but not both.
+ // |io_surface_| is non-NULL if the IOSurface APIs are supported (Mac OS X
+ // 10.6 and later).
+ // TODO(dspringer,kbr): Should the GPU backing store be encapsulated in its
+ // own class so all this implementation detail is hidden?
scoped_cftyperef<CFTypeRef> io_surface_;
+ // TODO(dspringer): If we end up keeping this TransportDIB mechanism, this
+ // should really be a scoped_ptr_malloc<>, with a deallocate functor that
+ // runs |dib_free_callback_|. I was not able to figure out how to
+ // make this work (or even compile).
+ scoped_ptr<TransportDIB> transport_dib_;
int32 surface_width_;
int32 surface_height_;
GLuint texture_;
GLuint fbo_;
- GLuint depth_renderbuffer_;
+ GLuint depth_stencil_renderbuffer_;
// For tracking whether the default framebuffer / renderbuffer or
// ones created by the end user are currently bound
GLuint bound_fbo_;
GLuint bound_renderbuffer_;
+ // Allocate a TransportDIB in the renderer.
+ scoped_ptr<Callback2<size_t, TransportDIB::Handle*>::Type>
+ dib_alloc_callback_;
+ scoped_ptr<Callback1<TransportDIB::Id>::Type> dib_free_callback_;
#endif
bool anti_aliased_;
@@ -641,7 +689,7 @@ GLES2DecoderImpl::GLES2DecoderImpl()
surface_height_(0),
texture_(0),
fbo_(0),
- depth_renderbuffer_(0),
+ depth_stencil_renderbuffer_(0),
bound_fbo_(0),
bound_renderbuffer_(0),
#endif
@@ -1144,7 +1192,70 @@ static void AddIntegerValue(CFMutableDictionaryRef dictionary,
}
#endif // !defined(UNIT_TEST)
-uint64 GLES2DecoderImpl::SetWindowSize(int32 width, int32 height) {
+void GLES2DecoderImpl::AllocateRenderBuffers(GLenum target,
+ int32 width, int32 height) {
+ if (!texture_) {
+ // Generate the texture object.
+ glGenTextures(1, &texture_);
+ glBindTexture(target, texture_);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ // Generate and bind the framebuffer object.
+ glGenFramebuffersEXT(1, &fbo_);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
+ bound_fbo_ = fbo_;
+ // Generate (but don't bind) the depth buffer -- we don't need
+ // this bound in order to do offscreen rendering.
+ glGenRenderbuffersEXT(1, &depth_stencil_renderbuffer_);
+ }
+
+ // Reallocate the depth buffer.
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_renderbuffer_);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
+ GL_DEPTH24_STENCIL8_EXT,
+ width,
+ height);
+
+ // Unbind the renderbuffers.
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, bound_renderbuffer_);
+
+ // Make sure that subsequent set-up code affects the render texture.
+ glBindTexture(target, texture_);
+}
+
+bool GLES2DecoderImpl::SetupFrameBufferObject(GLenum target) {
+ if (bound_fbo_ != fbo_) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
+ }
+ GLenum fbo_status;
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ target,
+ texture_,
+ 0);
+ fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT) {
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT,
+ depth_stencil_renderbuffer_);
+ fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ }
+ // Attach the depth and stencil buffer.
+ if (fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT) {
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER_EXT,
+ depth_stencil_renderbuffer_);
+ fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ }
+ if (bound_fbo_ != fbo_) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
+ }
+ return fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT;
+}
+
+uint64 GLES2DecoderImpl::SetWindowSizeForIOSurface(int32 width, int32 height) {
#if defined(UNIT_TEST)
return 0;
#else
@@ -1156,7 +1267,7 @@ uint64 GLES2DecoderImpl::SetWindowSize(int32 width, int32 height) {
IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
if (!io_surface_support)
- return 0;
+ return 0; // Caller can try using SetWindowSizeForTransportDIB().
if (!MakeCurrent())
return 0;
@@ -1164,21 +1275,7 @@ uint64 GLES2DecoderImpl::SetWindowSize(int32 width, int32 height) {
// GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
// Mac OS X and is required for IOSurface interoperability.
GLenum target = GL_TEXTURE_RECTANGLE_ARB;
-
- if (!texture_) {
- // Generate the texture object.
- glGenTextures(1, &texture_);
- glBindTexture(target, texture_);
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- // Generate and bind the framebuffer object.
- glGenFramebuffersEXT(1, &fbo_);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
- bound_fbo_ = fbo_;
- // Generate (but don't bind) the depth buffer -- we don't need
- // this bound in order to do offscreen rendering.
- glGenRenderbuffersEXT(1, &depth_renderbuffer_);
- }
+ AllocateRenderBuffers(target, width, height);
// Allocate a new IOSurface, which is the GPU resource that can be
// shared across processes.
@@ -1200,16 +1297,6 @@ uint64 GLES2DecoderImpl::SetWindowSize(int32 width, int32 height) {
// ultimately reference counted by the operating system.
io_surface_.reset(io_surface_support->IOSurfaceCreate(properties));
- // Reallocate the depth buffer.
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_renderbuffer_);
- glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
- GL_DEPTH_COMPONENT,
- width,
- height);
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, bound_renderbuffer_);
-
- // Reallocate the texture object.
- glBindTexture(target, texture_);
// Don't think we need to identify a plane.
GLuint plane = 0;
io_surface_support->CGLTexImageIOSurface2D(gl_context_,
@@ -1221,24 +1308,8 @@ uint64 GLES2DecoderImpl::SetWindowSize(int32 width, int32 height) {
GL_UNSIGNED_INT_8_8_8_8_REV,
io_surface_.get(),
plane);
-
// Set up the frame buffer object.
- if (bound_fbo_ != fbo_) {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
- }
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- target,
- texture_,
- 0);
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
- GL_DEPTH_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT,
- depth_renderbuffer_);
- if (bound_fbo_ != fbo_) {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
- }
-
+ SetupFrameBufferObject(target);
surface_width_ = width;
surface_height_ = height;
@@ -1252,6 +1323,68 @@ uint64 GLES2DecoderImpl::SetWindowSize(int32 width, int32 height) {
return io_surface_support->IOSurfaceGetID(io_surface_);
#endif // !defined(UNIT_TEST)
}
+
+TransportDIB::Handle GLES2DecoderImpl::SetWindowSizeForTransportDIB(
+ int32 width, int32 height) {
+#if defined(UNIT_TEST)
+ return TransportDIB::DefaultHandleValue();
+#else
+ if (surface_width_ == width && surface_height_ == height) {
+ // Return an invalid handle to indicate to the caller that no new backing
+ // store allocation occurred.
+ return TransportDIB::DefaultHandleValue();
+ }
+ surface_width_ = width;
+ surface_height_ = height;
+
+ // Release the old TransportDIB in the browser.
+ if (dib_free_callback_.get() && transport_dib_.get()) {
+ dib_free_callback_->Run(transport_dib_->id());
+ }
+ transport_dib_.reset();
+
+ // Ask the renderer to create a TransportDIB.
+ size_t dib_size = width * 4 * height; // 4 bytes per pixel.
+ TransportDIB::Handle dib_handle;
+ if (dib_alloc_callback_.get()) {
+ dib_alloc_callback_->Run(dib_size, &dib_handle);
+ }
+ if (!TransportDIB::is_valid(dib_handle)) {
+ // If the allocator fails, it means the DIB was not created in the browser,
+ // so there is no need to run the deallocator here.
+ return TransportDIB::DefaultHandleValue();
+ }
+ transport_dib_.reset(TransportDIB::Map(dib_handle));
+ if (transport_dib_.get() == NULL) {
+ // TODO(dspringer): if the Map() fails, should the deallocator be run so
+ // that the DIB is deallocated in the browser?
+ return TransportDIB::DefaultHandleValue();
+ }
+
+ // Set up the render buffers and reserve enough space on the card for the
+ // framebuffer texture.
+ GLenum target = GL_TEXTURE_RECTANGLE_ARB;
+ AllocateRenderBuffers(target, width, height);
+ glTexImage2D(target,
+ 0, // mipmap level 0
+ GL_RGBA8, // internal pixel format
+ width,
+ height,
+ 0, // 0 border
+ GL_BGRA, // Used for consistency
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ NULL); // No data, just reserve room on the card.
+ SetupFrameBufferObject(target);
+ return transport_dib_->handle();
+#endif // !defined(UNIT_TEST)
+}
+
+void GLES2DecoderImpl::SetTransportDIBAllocAndFree(
+ Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
+ Callback1<TransportDIB::Id>::Type* deallocator) {
+ dib_alloc_callback_.reset(allocator);
+ dib_free_callback_.reset(deallocator);
+}
#endif // defined(OS_MACOSX)
void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) {
@@ -1264,6 +1397,11 @@ void GLES2DecoderImpl::Destroy() {
DCHECK(window());
window()->Destroy();
#elif defined(OS_MACOSX)
+ // Release the old TransportDIB in the browser.
+ if (dib_free_callback_.get() && transport_dib_.get()) {
+ dib_free_callback_->Run(transport_dib_->id());
+ }
+ transport_dib_.reset();
if (gl_context_)
CGLDestroyContext(gl_context_);
if (pbuffer_)
@@ -1481,12 +1619,36 @@ void GLES2DecoderImpl::DoSwapBuffers() {
DCHECK(window());
window()->SwapBuffers();
#elif defined(OS_MACOSX)
- if (bound_fbo_ == fbo_) {
+ if (bound_fbo_ != fbo_) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
+ }
+ if (io_surface_.get() != NULL) {
// Bind and unbind the framebuffer to make changes to the
// IOSurface show up in the other process.
glFlush();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
+ } else if (transport_dib_.get() != NULL) {
+ // Pre-Mac OS X 10.6, fetch the rendered image from the FBO and copy it
+ // into the TransportDIB.
+ // TODO(dspringer): There are a couple of options that can speed this up.
+ // First is to use async reads into a PBO, second is to use SPI that
+ // allows many tasks to access the same CGSSurface.
+ void* pixel_memory = transport_dib_->memory();
+ if (pixel_memory) {
+ // Note that glReadPixels does an implicit glFlush().
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glReadPixels(0,
+ 0,
+ surface_width_,
+ surface_height_,
+ GL_BGRA, // This pixel format should have no conversion.
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ pixel_memory);
+ }
+ }
+ if (bound_fbo_ != fbo_) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
}
#endif
if (swap_buffers_callback_.get()) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index b3e9030..2b6f4e0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -12,8 +12,12 @@
#include <windows.h>
#endif
#include "base/callback.h"
+#if defined(OS_MACOSX)
+#include "chrome/common/transport_dib.h"
+#endif
#include "gpu/command_buffer/service/common_decoder.h"
+
namespace gpu {
// Forward-declared instead of including x_utils.h, because including glx.h
// causes havok.
@@ -57,7 +61,12 @@ class GLES2Decoder : public CommonDecoder {
return hwnd_;
}
#elif defined(OS_MACOSX)
- virtual uint64 SetWindowSize(int32 width, int32 height) = 0;
+ virtual uint64 SetWindowSizeForIOSurface(int32 width, int32 height) = 0;
+ virtual TransportDIB::Handle SetWindowSizeForTransportDIB(int32 width,
+ int32 height) = 0;
+ virtual void SetTransportDIBAllocAndFree(
+ Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
+ Callback1<TransportDIB::Id>::Type* deallocator) = 0;
#endif
// Initializes the graphics context.
diff --git a/gpu/command_buffer/service/gpu_processor.cc b/gpu/command_buffer/service/gpu_processor.cc
index 69fe8fb..e72ed06 100644
--- a/gpu/command_buffer/service/gpu_processor.cc
+++ b/gpu/command_buffer/service/gpu_processor.cc
@@ -84,8 +84,19 @@ int32 GPUProcessor::GetGetOffset() {
}
#if defined(OS_MACOSX)
-uint64 GPUProcessor::SetWindowSize(int32 width, int32 height) {
- return decoder_->SetWindowSize(width, height);
+uint64 GPUProcessor::SetWindowSizeForIOSurface(int32 width, int32 height) {
+ return decoder_->SetWindowSizeForIOSurface(width, height);
+}
+
+TransportDIB::Handle GPUProcessor::SetWindowSizeForTransportDIB(int32 width,
+ int32 height) {
+ return decoder_->SetWindowSizeForTransportDIB(width, height);
+}
+
+void GPUProcessor::SetTransportDIBAllocAndFree(
+ Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
+ Callback1<TransportDIB::Id>::Type* deallocator) {
+ decoder_->SetTransportDIBAllocAndFree(allocator, deallocator);
}
#endif
diff --git a/gpu/command_buffer/service/gpu_processor.h b/gpu/command_buffer/service/gpu_processor.h
index 8b8d350..4b82374 100644
--- a/gpu/command_buffer/service/gpu_processor.h
+++ b/gpu/command_buffer/service/gpu_processor.h
@@ -48,8 +48,15 @@ class GPUProcessor : public base::RefCounted<GPUProcessor>,
// Needed only on Mac OS X, which does not render into an on-screen
// window and therefore requires the backing store to be resized
// manually. Returns an opaque identifier for the new backing store.
- virtual uint64 SetWindowSize(int32 width, int32 height);
-
+ // There are two versions of this method: one for use with the IOSurface
+ // available in Mac OS X 10.6; and, one for use with the
+ // TransportDIB-based version used on Mac OS X 10.5.
+ virtual uint64 SetWindowSizeForIOSurface(int32 width, int32 height);
+ virtual TransportDIB::Handle SetWindowSizeForTransportDIB(int32 width,
+ int32 height);
+ virtual void SetTransportDIBAllocAndFree(
+ Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
+ Callback1<TransportDIB::Id>::Type* deallocator);
#endif
// Sets a callback which is called when a SwapBuffers command is processed.