diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-03 21:55:23 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-03 21:55:23 +0000 |
commit | 724744a42b7200ac7aa914c1fd51b0efe9506e9f (patch) | |
tree | bca5e1459fa74aa11d777a90bc3d0ed9418ac27c /webkit/gpu | |
parent | 8760b7c814cf5b5573eae468ae316aaf32d91ccd (diff) | |
download | chromium_src-724744a42b7200ac7aa914c1fd51b0efe9506e9f.zip chromium_src-724744a42b7200ac7aa914c1fd51b0efe9506e9f.tar.gz chromium_src-724744a42b7200ac7aa914c1fd51b0efe9506e9f.tar.bz2 |
make command buffer work in DRT
Note several tests get different results than the non-command buffer path.
I'm not sure if that's bugs in this impl, bugs in the command buffer
or bugs else where but that's kind of the point. This CL is supposed
to help find those bugs.
Is there something I should do to mark them to be fixed before
checking this in? Should I leave webkit_support.cc out of this
CL?
TEST=ran layout tests
BUG=84157
R=jamesr@chromium.org
Review URL: http://codereview.chromium.org/7085002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87879 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/gpu')
-rw-r--r-- | webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc | 2327 | ||||
-rw-r--r-- | webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h | 584 | ||||
-rw-r--r-- | webkit/gpu/webkit_gpu.gypi | 8 |
3 files changed, 1514 insertions, 1405 deletions
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc index dfb4959..db6010f 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc @@ -2,574 +2,912 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#if defined(ENABLE_GPU) + #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" -#include <string.h> +#include <GLES2/gl2.h> +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES 1 +#endif +#include <GLES2/gl2ext.h> #include <algorithm> -#include <string> +#include "base/string_tokenizer.h" +#include "base/command_line.h" +#include "base/lazy_instance.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/singleton.h" +#include "base/metrics/histogram.h" +#include "gpu/command_buffer/client/gles2_lib.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "gpu/command_buffer/common/constants.h" +#include "gpu/command_buffer/service/gpu_scheduler.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/GLES2/gles2_command_buffer.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" -#include "ui/gfx/gl/gl_bindings.h" -#include "ui/gfx/gl/gl_bindings_skia_in_process.h" -#include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/gl/gl_implementation.h" -#include "ui/gfx/gl/gl_surface.h" +#include "webkit/glue/gl_bindings_skia_cmd_buffer.h" + +using gpu::Buffer; +using gpu::CommandBuffer; +using gpu::CommandBufferService; +using gpu::gles2::GLES2CmdHelper; +using gpu::gles2::GLES2Implementation; +using gpu::GpuScheduler; namespace webkit { namespace gpu { -enum { - MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB, - MAX_VARYING_VECTORS = 0x8DFC, - MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD -}; +class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> { + public: + // These are the same error codes as used by EGL. + enum Error { + SUCCESS = 0x3000, + NOT_INITIALIZED = 0x3001, + BAD_ATTRIBUTE = 0x3004, + BAD_GLContext = 0x3006, + CONTEXT_LOST = 0x300E + }; + + // GLInProcessContext configuration attributes. These are the same as used by + // EGL. Attributes are matched using a closest fit algorithm. + enum Attribute { + ALPHA_SIZE = 0x3021, + BLUE_SIZE = 0x3022, + GREEN_SIZE = 0x3023, + RED_SIZE = 0x3024, + DEPTH_SIZE = 0x3025, + STENCIL_SIZE = 0x3026, + SAMPLES = 0x3031, + SAMPLE_BUFFERS = 0x3032, + NONE = 0x3038 // Attrib list = terminator + }; + + // Initialize the library. This must have completed before any other + // functions are invoked. + static bool Initialize(); + + // Terminate the library. This must be called after any other functions + // have completed. + static bool Terminate(); + + ~GLInProcessContext(); + + // Create a GLInProcessContext that renders directly to a view. The view and + // the associated window must not be destroyed until the returned + // GLInProcessContext has been destroyed, otherwise the GPU process might + // attempt to render to an invalid window handle. + // + // NOTE: on Mac OS X, this entry point is only used to set up the + // accelerated compositor's output. On this platform, we actually pass + // a gfx::PluginWindowHandle in place of the gfx::NativeViewId, + // because the facility to allocate a fake PluginWindowHandle is + // already in place. We could add more entry points and messages to + // allocate both fake PluginWindowHandles and NativeViewIds and map + // from fake NativeViewIds to PluginWindowHandles, but this seems like + // unnecessary complexity at the moment. + // + static GLInProcessContext* CreateViewContext( + gfx::PluginWindowHandle render_surface, + const char* allowed_extensions, + const int32* attrib_list, + const GURL& active_arl); -struct WebGraphicsContext3DInProcessCommandBufferImpl::ShaderSourceEntry { - explicit ShaderSourceEntry(WGC3Denum shader_type) - : type(shader_type), - is_valid(false) { - } +#if defined(OS_MACOSX) + // On Mac OS X only, view GLInProcessContexts actually behave like offscreen + // GLInProcessContexts, and require an explicit resize operation which is + // slightly different from that of offscreen GLInProcessContexts. + void ResizeOnscreen(const gfx::Size& size); +#endif - WGC3Denum type; - scoped_array<char> source; - scoped_array<char> log; - scoped_array<char> translated_source; - bool is_valid; + // Create a GLInProcessContext that renders to an offscreen frame buffer. If + // parent is not NULL, that GLInProcessContext can access a copy of the + // created GLInProcessContext's frame buffer that is updated every time + // SwapBuffers is called. It is not as general as shared GLInProcessContexts + // in other implementations of OpenGL. If parent is not NULL, it must be used + // on the same thread as the parent. A child GLInProcessContext may not + // outlive its parent. attrib_list must be NULL or a NONE-terminated list of + // attribute/value pairs. + static GLInProcessContext* CreateOffscreenContext( + GLInProcessContext* parent, + const gfx::Size& size, + const char* allowed_extensions, + const int32* attrib_list, + const GURL& active_url); + + // Resize an offscreen frame buffer. The resize occurs on the next call to + // SwapBuffers. This is to avoid waiting until all pending GL calls have been + // executed by the GPU process. Everything rendered up to the call to + // SwapBuffers will be lost. A lost GLInProcessContext will be reported if the + // resize fails. + void ResizeOffscreen(const gfx::Size& size); + + // For an offscreen frame buffer GLInProcessContext, return the texture ID + // with respect to the parent GLInProcessContext. Returns zero if + // GLInProcessContext does not have a parent. + uint32 GetParentTextureId(); + + // Create a new texture in the parent's GLInProcessContext. Returns zero if + // GLInProcessContext does not have a parent. + uint32 CreateParentTexture(const gfx::Size& size); + + // Deletes a texture in the parent's GLInProcessContext. + void DeleteParentTexture(uint32 texture); + + // Provides a callback that will be invoked when SwapBuffers has completed + // service side. + void SetSwapBuffersCallback(Callback0::Type* callback); + + void SetContextLostCallback(Callback0::Type* callback); + + // Set the current GLInProcessContext for the calling thread. + static bool MakeCurrent(GLInProcessContext* context); + + // For a view GLInProcessContext, display everything that has been rendered + // since the last call. For an offscreen GLInProcessContext, resolve + // everything that has been rendered since the last call to a copy that can be + // accessed by the parent GLInProcessContext. + bool SwapBuffers(); + + // TODO(gman): Remove this + void DisableShaderTranslation(); + + // Allows direct access to the GLES2 implementation so a GLInProcessContext + // can be used without making it current. + GLES2Implementation* GetImplementation(); + + // Return the current error. + Error GetError(); + + // Return true if GPU process reported GLInProcessContext lost or there was a + // problem communicating with the GPU process. + bool IsCommandBufferContextLost(); + + CommandBufferService* GetCommandBufferService(); + + // Create a latch for synchronization between contexts using glSetLatch and + // glWaitLatch. + // CreateLatch will only fail if there is a generally unrecoverable + // error, in which case 0 is returned. Returns latch_id on success. + bool CreateLatch(uint32* ret_latch); + + // Destroy a latch. + bool DestroyLatch(uint32 latch); + + // All child contexts get a latch pair automatically. These latches are used + // for synchronization with parent context. If *this* context does not have a + // parent context, these methods will return false. + bool GetParentToChildLatch(uint32* parent_to_child_latch); + bool GetChildToParentLatch(uint32* child_to_parent_latch); + + private: + GLInProcessContext(GLInProcessContext* parent); + + bool Initialize(bool onscreen, + gfx::PluginWindowHandle render_surface, + const gfx::Size& size, + const char* allowed_extensions, + const int32* attrib_list, + const GURL& active_url); + void Destroy(); + + void OnSwapBuffers(); + void OnContextLost(); + + base::WeakPtr<GLInProcessContext> parent_; + scoped_ptr<Callback0::Type> swap_buffers_callback_; + scoped_ptr<Callback0::Type> context_lost_callback_; + uint32 parent_texture_id_; + uint32 child_to_parent_latch_; + uint32 parent_to_child_latch_; + int32 latch_transfer_buffer_id_; + scoped_ptr<CommandBufferService> command_buffer_; + GpuScheduler* gpu_scheduler_; + GLES2CmdHelper* gles2_helper_; + int32 transfer_buffer_id_; + GLES2Implementation* gles2_implementation_; + gfx::Size size_; + Error last_error_; + + DISALLOW_COPY_AND_ASSIGN(GLInProcessContext); }; -WebGraphicsContext3DInProcessCommandBufferImpl::WebGraphicsContext3DInProcessCommandBufferImpl() - : initialized_(false), - render_directly_to_web_view_(false), - is_gles2_(false), - have_ext_framebuffer_object_(false), - have_ext_framebuffer_multisample_(false), - have_angle_framebuffer_multisample_(false), - texture_(0), - fbo_(0), - depth_stencil_buffer_(0), - cached_width_(0), - cached_height_(0), - multisample_fbo_(0), - multisample_depth_stencil_buffer_(0), - multisample_color_buffer_(0), - bound_fbo_(0), - bound_texture_(0), - copy_texture_to_parent_texture_fbo_(0), -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - scanline_(0), -#endif - fragment_compiler_(0), - vertex_compiler_(0) { -} +namespace { -WebGraphicsContext3DInProcessCommandBufferImpl::~WebGraphicsContext3DInProcessCommandBufferImpl() { - if (!initialized_) - return; +const int32 kCommandBufferSize = 1024 * 1024; +// TODO(kbr): make the transfer buffer size configurable via context +// creation attributes. +const int32 kTransferBufferSize = 1024 * 1024; - makeContextCurrent(); +const uint32 kMaxLatchesPerRenderer = 2048; +const uint32 kInvalidLatchId = 0xffffffffu; - if (attributes_.antialias) { - glDeleteRenderbuffersEXT(1, &multisample_color_buffer_); - if (attributes_.depth || attributes_.stencil) - glDeleteRenderbuffersEXT(1, &multisample_depth_stencil_buffer_); - glDeleteFramebuffersEXT(1, &multisample_fbo_); - } else { - if (attributes_.depth || attributes_.stencil) - glDeleteRenderbuffersEXT(1, &depth_stencil_buffer_); +// Singleton used to initialize and terminate the gles2 library. +class GLES2Initializer { + public: + GLES2Initializer() { + gles2::Initialize(); } - glDeleteTextures(1, &texture_); - glDeleteFramebuffersEXT(1, ©_texture_to_parent_texture_fbo_); -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (scanline_) - delete[] scanline_; -#endif - glDeleteFramebuffersEXT(1, &fbo_); - gl_context_->Destroy(); - - for (ShaderSourceMap::iterator ii = shader_source_map_.begin(); - ii != shader_source_map_.end(); ++ii) { - if (ii->second) - delete ii->second; + ~GLES2Initializer() { + gles2::Terminate(); } - AngleDestroyCompilers(); -} -bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize( - WebGraphicsContext3D::Attributes attributes, - WebView* webView, - bool render_directly_to_web_view) { - if (!gfx::GLSurface::InitializeOneOff()) - return false; - gfx::BindSkiaToInProcessGL(); + private: + DISALLOW_COPY_AND_ASSIGN(GLES2Initializer); +}; - render_directly_to_web_view_ = render_directly_to_web_view; - gfx::GLContext* share_context = 0; +// Allocator for latches. +class LatchAllocator { + public: + static LatchAllocator* GetInstance(); + static uint32 size() { return kMaxLatchesPerRenderer*sizeof(uint32); } + static const uint32_t kFreeLatch = 0xffffffffu; - if (!render_directly_to_web_view) { - // Pick up the compositor's context to share resources with. - WebGraphicsContext3D* view_context = webView->graphicsContext3D(); - if (view_context) { - WebGraphicsContext3DInProcessCommandBufferImpl* contextImpl = - static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>(view_context); - share_context = contextImpl->gl_context_.get(); - } else { - // The compositor's context didn't get created - // successfully, so conceptually there is no way we can - // render successfully to the WebView. - render_directly_to_web_view_ = false; - } - } + LatchAllocator(); + ~LatchAllocator(); - is_gles2_ = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; + bool AllocateLatch(uint32* latch_id); + bool FreeLatch(uint32 latch_id); - // This implementation always renders offscreen regardless of - // whether render_directly_to_web_view is true. Both DumpRenderTree - // and test_shell paint first to an intermediate offscreen buffer - // and from there to the window, and WebViewImpl::paint already - // correctly handles the case where the compositor is active but - // the output needs to go to a WebCanvas. - gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); + private: + friend struct DefaultSingletonTraits<LatchAllocator>; - if (!gl_surface_.get()) { - if (!is_gles2_) - return false; + scoped_array<uint32> latches_; - // Embedded systems have smaller limit on number of GL contexts. Sometimes - // failure of GL context creation is because of existing GL contexts - // referenced by JavaScript garbages. Collect garbage and try again. - // TODO: Besides this solution, kbr@chromium.org suggested: upon receiving - // a page unload event, iterate down any live WebGraphicsContext3D instances - // and force them to drop their contexts, sending a context lost event if - // necessary. - webView->mainFrame()->collectGarbage(); - - gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); - if (!gl_surface_.get()) - return false; - } + DISALLOW_COPY_AND_ASSIGN(LatchAllocator); +}; - gl_context_ = gfx::GLContext::CreateGLContext(share_context, - gl_surface_.get()); - if (!gl_context_.get()) { - if (!is_gles2_) - return false; +//////////////////////////////////////////////////////////////////////////////// +/// LatchAllocator implementation - // Embedded systems have smaller limit on number of GL contexts. Sometimes - // failure of GL context creation is because of existing GL contexts - // referenced by JavaScript garbages. Collect garbage and try again. - // TODO: Besides this solution, kbr@chromium.org suggested: upon receiving - // a page unload event, iterate down any live WebGraphicsContext3D instances - // and force them to drop their contexts, sending a context lost event if - // necessary. - webView->mainFrame()->collectGarbage(); - - gl_context_ = gfx::GLContext::CreateGLContext(share_context, - gl_surface_.get()); - if (!gl_context_.get()) - return false; - } +LatchAllocator* LatchAllocator::GetInstance() { + return Singleton<LatchAllocator>::get(); +} - attributes_ = attributes; - - // FIXME: for the moment we disable multisampling for the compositor. - // It actually works in this implementation, but there are a few - // considerations. First, we likely want to reduce the fuzziness in - // these tests as much as possible because we want to run pixel tests. - // Second, Mesa's multisampling doesn't seem to antialias straight - // edges in some CSS 3D samples. Third, we don't have multisampling - // support for the compositor in the normal case at the time of this - // writing. - if (render_directly_to_web_view) - attributes_.antialias = false; - - if (!gl_context_->MakeCurrent(gl_surface_.get())) { - gl_context_ = NULL; - return false; - } +LatchAllocator::LatchAllocator() { + latches_.reset(new uint32[size()]); + // Mark all latches as unallocated. + for (uint32 i = 0; i < kMaxLatchesPerRenderer; ++i) + latches_[i] = kFreeLatch; +} - const char* extensions = - reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); - DCHECK(extensions); - have_ext_framebuffer_object_ = - strstr(extensions, "GL_EXT_framebuffer_object") != NULL; - have_ext_framebuffer_multisample_ = - strstr(extensions, "GL_EXT_framebuffer_multisample") != NULL; - have_angle_framebuffer_multisample_ = - strstr(extensions, "GL_ANGLE_framebuffer_multisample") != NULL; - - ValidateAttributes(); - - if (!is_gles2_) { - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_POINT_SPRITE); +LatchAllocator::~LatchAllocator() { +} + +bool LatchAllocator::AllocateLatch(uint32* latch_id) { + for (uint32 i = 0; i < kMaxLatchesPerRenderer; ++i) { + if (latches_[i] == kFreeLatch) { + // mark latch as taken and blocked. + // 0 means waiter will block, 1 means waiter will pass. + latches_[i] = 0; + *latch_id = i; + return true; + } } + return false; +} - if (!AngleCreateCompilers()) { - AngleDestroyCompilers(); - return false; +bool LatchAllocator::FreeLatch(uint32 latch_id) { + if (latch_id < kMaxLatchesPerRenderer && latches_[latch_id] != kFreeLatch) { + latches_[latch_id] = kFreeLatch; + return true; } + return false; +} - glGenFramebuffersEXT(1, ©_texture_to_parent_texture_fbo_); +//////////////////////////////////////////////////////////////////////////////// - initialized_ = true; - return true; +static base::LazyInstance<GLES2Initializer> g_gles2_initializer( + base::LINKER_INITIALIZED); + +} // namespace anonymous + +GLInProcessContext::~GLInProcessContext() { + Destroy(); } -void WebGraphicsContext3DInProcessCommandBufferImpl::ValidateAttributes() { - const char* extensions = - reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); +GLInProcessContext* GLInProcessContext::CreateViewContext( + gfx::PluginWindowHandle render_surface, + const char* allowed_extensions, + const int32* attrib_list, + const GURL& active_url) { +#if defined(ENABLE_GPU) + scoped_ptr<GLInProcessContext> context(new GLInProcessContext(NULL)); + if (!context->Initialize( + true, + render_surface, + gfx::Size(), + allowed_extensions, + attrib_list, + active_url)) + return NULL; + + return context.release(); +#else + return NULL; +#endif +} - if (attributes_.stencil) { - if (strstr(extensions, "GL_OES_packed_depth_stencil") || - strstr(extensions, "GL_EXT_packed_depth_stencil")) { - if (!attributes_.depth) { - attributes_.depth = true; - } - } else { - attributes_.stencil = false; - } - } - if (attributes_.antialias) { - bool isValidVendor = true; #if defined(OS_MACOSX) - // Currently in Mac we only turn on antialias if vendor is NVIDIA. - const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); - if (!strstr(vendor, "NVIDIA")) - isValidVendor = false; +void GLInProcessContext::ResizeOnscreen(const gfx::Size& size) { + DCHECK(size.width() > 0 && size.height() > 0); + size_ = size; +} #endif - if (!(isValidVendor && - (have_ext_framebuffer_multisample_ || - (have_angle_framebuffer_multisample_ && - strstr(extensions, "GL_OES_rgb8_rgba8"))))) - attributes_.antialias = false; - - // Don't antialias when using Mesa to ensure more reliable testing and - // because it doesn't appear to multisample straight lines correctly. - const char* renderer = - reinterpret_cast<const char*>(glGetString(GL_RENDERER)); - if (!strncmp(renderer, "Mesa", 4)) { - attributes_.antialias = false; - } + +GLInProcessContext* GLInProcessContext::CreateOffscreenContext( + GLInProcessContext* parent, + const gfx::Size& size, + const char* allowed_extensions, + const int32* attrib_list, + const GURL& active_url) { +#if defined(ENABLE_GPU) + scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent)); + if (!context->Initialize( + false, + gfx::kNullPluginWindow, + size, + allowed_extensions, + attrib_list, + active_url)) + return NULL; + + return context.release(); +#else + return NULL; +#endif +} + +void GLInProcessContext::ResizeOffscreen(const gfx::Size& size) { + DCHECK(size.width() > 0 && size.height() > 0); + if (size_ != size) { + gpu_scheduler_->ResizeOffscreenFrameBuffer(size); + // TODO(gman): See if the next line is needed. + gles2_implementation_->ResizeCHROMIUM(size.width(), size.height()); + size_ = size; } } -void WebGraphicsContext3DInProcessCommandBufferImpl::ResolveMultisampledFramebuffer( - WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) { - if (attributes_.antialias) { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, multisample_fbo_); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo_); - if (have_ext_framebuffer_multisample_) { - glBlitFramebufferEXT(x, y, - x + width, y + height, - x, y, - x + width, y + height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else { - DCHECK(have_angle_framebuffer_multisample_); - glBlitFramebufferANGLE(x, y, - x + width, y + height, - x, y, - x + width, y + height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); +uint32 GLInProcessContext::GetParentTextureId() { + return parent_texture_id_; +} + +uint32 GLInProcessContext::CreateParentTexture(const gfx::Size& size) { + // Allocate a texture ID with respect to the parent. + if (parent_.get()) { + if (!MakeCurrent(parent_.get())) + return 0; + uint32 texture_id = parent_->gles2_implementation_->MakeTextureId(); + parent_->gles2_implementation_->BindTexture(GL_TEXTURE_2D, texture_id); + parent_->gles2_implementation_->TexParameteri( + GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + parent_->gles2_implementation_->TexParameteri( + GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + parent_->gles2_implementation_->TexParameteri( + GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + parent_->gles2_implementation_->TexParameteri( + GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + parent_->gles2_implementation_->TexImage2D(GL_TEXTURE_2D, + 0, // mip level + GL_RGBA, + size.width(), + size.height(), + 0, // border + GL_RGBA, + GL_UNSIGNED_BYTE, + NULL); + // Make sure that the parent texture's storage is allocated before we let + // the caller attempt to use it. + int32 token = parent_->gles2_helper_->InsertToken(); + parent_->gles2_helper_->WaitForToken(token); + return texture_id; } + return 0; } -bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() { - return gl_context_->MakeCurrent(gl_surface_.get()); +void GLInProcessContext::DeleteParentTexture(uint32 texture) { + if (parent_.get()) { + if (!MakeCurrent(parent_.get())) + return; + parent_->gles2_implementation_->DeleteTextures(1, &texture); + } } -int WebGraphicsContext3DInProcessCommandBufferImpl::width() { - return cached_width_; +void GLInProcessContext::SetSwapBuffersCallback(Callback0::Type* callback) { + swap_buffers_callback_.reset(callback); } -int WebGraphicsContext3DInProcessCommandBufferImpl::height() { - return cached_height_; +void GLInProcessContext::SetContextLostCallback(Callback0::Type* callback) { + context_lost_callback_.reset(callback); } -bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() { - return is_gles2_; +bool GLInProcessContext::MakeCurrent(GLInProcessContext* context) { + if (context) { + gles2::SetGLContext(context->gles2_implementation_); + + // Don't request latest error status from service. Just use the locally + // cached information from the last flush. + // TODO(apatrick): I'm not sure if this should actually change the + // current context if it fails. For now it gets changed even if it fails + // because making GL calls with a NULL context crashes. + if (context->command_buffer_->GetState().error != ::gpu::error::kNoError) + return false; + } else { + gles2::SetGLContext(NULL); + } + + return true; } -WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() { - return texture_; +bool GLInProcessContext::SwapBuffers() { + // Don't request latest error status from service. Just use the locally cached + // information from the last flush. + if (command_buffer_->GetState().error != ::gpu::error::kNoError) + return false; + + gles2_implementation_->SwapBuffers(); + gles2_implementation_->Finish(); + return true; } -void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() { - if (!render_directly_to_web_view_) { - // We need to prepare our rendering results for the compositor. - makeContextCurrent(); - ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); +GLInProcessContext::Error GLInProcessContext::GetError() { + CommandBuffer::State state = command_buffer_->GetState(); + if (state.error == ::gpu::error::kNoError) { + Error old_error = last_error_; + last_error_ = SUCCESS; + return old_error; + } else { + // All command buffer errors are unrecoverable. The error is treated as a + // lost context: destroy the context and create another one. + return CONTEXT_LOST; } } -namespace { +bool GLInProcessContext::IsCommandBufferContextLost() { + CommandBuffer::State state = command_buffer_->GetState(); + return state.error == ::gpu::error::kLostContext; +} -int CreateTextureObject(GLenum target) { - GLuint texture = 0; - glGenTextures(1, &texture); - glBindTexture(target, texture); - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - return texture; +CommandBufferService* GLInProcessContext::GetCommandBufferService() { + return command_buffer_.get(); } -} // anonymous namespace +// TODO(gman): Remove This +void GLInProcessContext::DisableShaderTranslation() { + gles2_implementation_->CommandBufferEnableCHROMIUM( + PEPPER3D_SKIP_GLSL_TRANSLATION); +} -void WebGraphicsContext3DInProcessCommandBufferImpl::reshape(int width, int height) { - cached_width_ = width; - cached_height_ = height; - makeContextCurrent(); +GLES2Implementation* GLInProcessContext::GetImplementation() { + return gles2_implementation_; +} - GLenum target = GL_TEXTURE_2D; - - if (!texture_) { - // Generate the texture object - texture_ = CreateTextureObject(target); - // Generate the framebuffer object - glGenFramebuffersEXT(1, &fbo_); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - bound_fbo_ = fbo_; - if (attributes_.depth || attributes_.stencil) - glGenRenderbuffersEXT(1, &depth_stencil_buffer_); - // Generate the multisample framebuffer object - if (attributes_.antialias) { - glGenFramebuffersEXT(1, &multisample_fbo_); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_); - bound_fbo_ = multisample_fbo_; - glGenRenderbuffersEXT(1, &multisample_color_buffer_); - if (attributes_.depth || attributes_.stencil) - glGenRenderbuffersEXT(1, &multisample_depth_stencil_buffer_); - } - } +GLInProcessContext::GLInProcessContext(GLInProcessContext* parent) + : parent_(parent ? + parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()), + parent_texture_id_(0), + child_to_parent_latch_(kInvalidLatchId), + parent_to_child_latch_(kInvalidLatchId), + latch_transfer_buffer_id_(-1), + gpu_scheduler_(NULL), + gles2_helper_(NULL), + transfer_buffer_id_(-1), + gles2_implementation_(NULL), + last_error_(SUCCESS) { +} - GLint internal_multisampled_color_format = 0; - GLint internal_color_format = 0; - GLint color_format = 0; - GLint internal_depth_stencil_format = 0; - if (attributes_.alpha) { - // GL_RGBA8_OES == GL_RGBA8 - internal_multisampled_color_format = GL_RGBA8; - internal_color_format = is_gles2_ ? GL_RGBA : GL_RGBA8; - color_format = GL_RGBA; - } else { - // GL_RGB8_OES == GL_RGB8 - internal_multisampled_color_format = GL_RGB8; - internal_color_format = is_gles2_ ? GL_RGB : GL_RGB8; - color_format = GL_RGB; +bool GLInProcessContext::Initialize(bool onscreen, + gfx::PluginWindowHandle render_surface, + const gfx::Size& size, + const char* allowed_extensions, + const int32* attrib_list, + const GURL& active_url) { + DCHECK(size.width() >= 0 && size.height() >= 0); + + // Ensure the gles2 library is initialized first in a thread safe way. + g_gles2_initializer.Get(); + + // Allocate a frame buffer ID with respect to the parent. + if (parent_.get()) { + // Flush any remaining commands in the parent context to make sure the + // texture id accounting stays consistent. + int32 token = parent_->gles2_helper_->InsertToken(); + parent_->gles2_helper_->WaitForToken(token); + parent_texture_id_ = parent_->gles2_implementation_->MakeTextureId(); } - if (attributes_.stencil || attributes_.depth) { - // We don't allow the logic where stencil is required and depth is not. - // See GraphicsContext3DInternal constructor. - if (attributes_.stencil && attributes_.depth) { - internal_depth_stencil_format = GL_DEPTH24_STENCIL8_EXT; - } else { - if (is_gles2_) - internal_depth_stencil_format = GL_DEPTH_COMPONENT16; - else - internal_depth_stencil_format = GL_DEPTH_COMPONENT; + + std::vector<int32> attribs; + while (attrib_list) { + int32 attrib = *attrib_list++; + switch (attrib) { + // Known attributes + case ALPHA_SIZE: + case BLUE_SIZE: + case GREEN_SIZE: + case RED_SIZE: + case DEPTH_SIZE: + case STENCIL_SIZE: + case SAMPLES: + case SAMPLE_BUFFERS: + attribs.push_back(attrib); + attribs.push_back(*attrib_list++); + break; + case NONE: + attribs.push_back(attrib); + attrib_list = NULL; + break; + default: + last_error_ = BAD_ATTRIBUTE; + attribs.push_back(NONE); + attrib_list = NULL; + break; } } - bool must_restore_fbo = false; + command_buffer_.reset(new CommandBufferService); + if (!command_buffer_->Initialize(kCommandBufferSize)) + return false; - // Resize multisampling FBO - if (attributes_.antialias) { - GLint max_sample_count; - glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); - GLint sample_count = std::min(8, max_sample_count); - if (bound_fbo_ != multisample_fbo_) { - must_restore_fbo = true; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_); - } - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, multisample_color_buffer_); - if (have_ext_framebuffer_multisample_) { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, - sample_count, - internal_multisampled_color_format, - width, - height); + gpu_scheduler_ = new GpuScheduler(command_buffer_.get(), NULL, NULL); + + if (onscreen) { + if (render_surface == gfx::kNullPluginWindow) { + LOG(ERROR) << "Invalid surface handle for onscreen context."; + command_buffer_.reset(); } else { - DCHECK(have_angle_framebuffer_multisample_); - glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT, - sample_count, - internal_multisampled_color_format, - width, - height); - } - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_RENDERBUFFER_EXT, - multisample_color_buffer_); - if (attributes_.stencil || attributes_.depth) { - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, - multisample_depth_stencil_buffer_); - if (have_ext_framebuffer_multisample_) { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, - sample_count, - internal_depth_stencil_format, - width, - height); - } else { - DCHECK(have_angle_framebuffer_multisample_); - glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT, - sample_count, - internal_depth_stencil_format, - width, - height); + if (!gpu_scheduler_->Initialize(render_surface, + gfx::Size(), + ::gpu::gles2::DisallowedExtensions(), + allowed_extensions, + attribs, + NULL, + 0)) { + LOG(ERROR) << "Could not initialize GpuScheduler."; + command_buffer_.reset(); } - if (attributes_.stencil) - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - multisample_depth_stencil_buffer_); - if (attributes_.depth) - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - multisample_depth_stencil_buffer_); } - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - LOG(ERROR) << "Multisampling framebuffer was incomplete"; + } else { + GpuScheduler* parent_scheduler = + parent_.get() ? parent_->gpu_scheduler_ : NULL; + + if (!gpu_scheduler_->Initialize(render_surface, + size, + ::gpu::gles2::DisallowedExtensions(), + allowed_extensions, + attribs, + parent_scheduler, + parent_texture_id_)) { + LOG(ERROR) << "Could not initialize offscreen GpuScheduler."; + command_buffer_.reset(); + } + } + if (!command_buffer_.get()) { + Destroy(); + return false; + } + + command_buffer_->SetPutOffsetChangeCallback( + NewCallback(gpu_scheduler_, &GpuScheduler::PutChanged)); + + // Create the GLES2 helper, which writes the command buffer protocol. + gles2_helper_ = new GLES2CmdHelper(command_buffer_.get()); + if (!gles2_helper_->Initialize(kCommandBufferSize)) { + Destroy(); + return false; + } + + // Create a transfer buffer. + transfer_buffer_id_ = + command_buffer_->CreateTransferBuffer( + kTransferBufferSize, ::gpu::kCommandBufferSharedMemoryId); + if (transfer_buffer_id_ < 0) { + Destroy(); + return false; + } + + // Map the buffer. + Buffer transfer_buffer = + command_buffer_->GetTransferBuffer(transfer_buffer_id_); + if (!transfer_buffer.ptr) { + Destroy(); + return false; + } - // FIXME: cleanup. - NOTIMPLEMENTED(); + // If this is a child context, setup latches for synchronization between child + // and parent. + if (parent_.get()) { + if (!CreateLatch(&child_to_parent_latch_) || + !CreateLatch(&parent_to_child_latch_)) { + Destroy(); + return false; } } - // Resize regular FBO - if (bound_fbo_ != fbo_) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - must_restore_fbo = true; + // Create the object exposing the OpenGL API. + gles2_implementation_ = new GLES2Implementation( + gles2_helper_, + transfer_buffer.size, + transfer_buffer.ptr, + transfer_buffer_id_, + false); + + size_ = size; + + return true; +} + +void GLInProcessContext::Destroy() { + if (parent_.get() && parent_texture_id_ != 0) { + parent_->gles2_implementation_->FreeTextureId(parent_texture_id_); + parent_texture_id_ = 0; + } + + delete gles2_implementation_; + gles2_implementation_ = NULL; + + if (child_to_parent_latch_ != kInvalidLatchId) { + DestroyLatch(child_to_parent_latch_); + child_to_parent_latch_ = kInvalidLatchId; + } + if (parent_to_child_latch_ != kInvalidLatchId) { + DestroyLatch(parent_to_child_latch_); + parent_to_child_latch_ = kInvalidLatchId; } - glBindTexture(target, texture_); - glTexImage2D(target, 0, internal_color_format, - width, height, - 0, color_format, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, - texture_, - 0); - glBindTexture(target, 0); - if (!attributes_.antialias && (attributes_.stencil || attributes_.depth)) { - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer_); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - internal_depth_stencil_format, - width, height); - if (attributes_.stencil) - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - depth_stencil_buffer_); - if (attributes_.depth) - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - depth_stencil_buffer_); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + if (command_buffer_.get() && latch_transfer_buffer_id_ != -1) { + command_buffer_->DestroyTransferBuffer(latch_transfer_buffer_id_); + latch_transfer_buffer_id_ = -1; } - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - LOG(ERROR) << "Framebuffer was incomplete"; - // FIXME: cleanup. - NOTIMPLEMENTED(); + if (command_buffer_.get() && transfer_buffer_id_ != -1) { + command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); + transfer_buffer_id_ = -1; } - if (attributes_.antialias) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_); - if (bound_fbo_ == multisample_fbo_) - must_restore_fbo = false; + delete gles2_helper_; + gles2_helper_ = NULL; + + command_buffer_.reset(); +} + +void GLInProcessContext::OnSwapBuffers() { + if (swap_buffers_callback_.get()) + swap_buffers_callback_->Run(); +} + +void GLInProcessContext::OnContextLost() { + if (context_lost_callback_.get()) + context_lost_callback_->Run(); +} + +bool GLInProcessContext::CreateLatch(uint32* ret_latch) { + return LatchAllocator::GetInstance()->AllocateLatch(ret_latch); +} + +bool GLInProcessContext::DestroyLatch(uint32 latch) { + return LatchAllocator::GetInstance()->FreeLatch(latch); +} + +bool GLInProcessContext::GetParentToChildLatch(uint32* parent_to_child_latch) { + if (parent_.get()) { + *parent_to_child_latch = parent_to_child_latch_; + return true; } + return false; +} - // Initialize renderbuffers to 0. - GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0; - GLint clearStencil = 0; - GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}; - GLboolean depthMask = GL_TRUE; - GLuint stencilMask = 0xffffffff; - GLboolean isScissorEnabled = GL_FALSE; - GLboolean isDitherEnabled = GL_FALSE; - GLbitfield clearMask = GL_COLOR_BUFFER_BIT; - glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor); - glClearColor(0, 0, 0, 0); - glGetBooleanv(GL_COLOR_WRITEMASK, colorMask); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - if (attributes_.depth) { - glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth); - glClearDepth(1); - glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); - glDepthMask(GL_TRUE); - clearMask |= GL_DEPTH_BUFFER_BIT; +bool GLInProcessContext::GetChildToParentLatch(uint32* child_to_parent_latch) { + if (parent_.get()) { + *child_to_parent_latch = child_to_parent_latch_; + return true; } - if (attributes_.stencil) { - glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil); - glClearStencil(0); - glGetIntegerv(GL_STENCIL_WRITEMASK, - reinterpret_cast<GLint*>(&stencilMask)); - glStencilMaskSeparate(GL_FRONT, 0xffffffff); - clearMask |= GL_STENCIL_BUFFER_BIT; + return false; +} + +WebGraphicsContext3DInProcessCommandBufferImpl:: + WebGraphicsContext3DInProcessCommandBufferImpl() + : context_(NULL), + gl_(NULL), + web_view_(NULL), +#if defined(OS_MACOSX) + plugin_handle_(NULL), +#endif // defined(OS_MACOSX) + context_lost_callback_(0), + cached_width_(0), + cached_height_(0), + bound_fbo_(0) { +} + +WebGraphicsContext3DInProcessCommandBufferImpl:: + ~WebGraphicsContext3DInProcessCommandBufferImpl() { +} + +// This string should only be passed for WebGL contexts. Nothing ELSE!!! +// Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of +// a context should not pass this string. +static const char* kWebGLPreferredGLExtensions = + "GL_OES_packed_depth_stencil " + "GL_OES_depth24 " + "GL_CHROMIUM_webglsl"; + +bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize( + WebGraphicsContext3D::Attributes attributes, + WebKit::WebView* web_view, + bool render_directly_to_web_view) { + webkit_glue::BindSkiaToCommandBufferGL(); + + // Convert WebGL context creation attributes into GLInProcessContext / EGL + // size requests. + const int alpha_size = attributes.alpha ? 8 : 0; + const int depth_size = attributes.depth ? 24 : 0; + const int stencil_size = attributes.stencil ? 8 : 0; + const int samples = attributes.antialias ? 4 : 0; + const int sample_buffers = attributes.antialias ? 1 : 0; + const int32 attribs[] = { + GLInProcessContext::ALPHA_SIZE, alpha_size, + GLInProcessContext::DEPTH_SIZE, depth_size, + GLInProcessContext::STENCIL_SIZE, stencil_size, + GLInProcessContext::SAMPLES, samples, + GLInProcessContext::SAMPLE_BUFFERS, sample_buffers, + GLInProcessContext::NONE, + }; + + const char* preferred_extensions = attributes.noExtensions ? + kWebGLPreferredGLExtensions : "*"; + + GURL active_url; + if (web_view && web_view->mainFrame()) + active_url = GURL(web_view->mainFrame()->url()); + + GLInProcessContext* parent_context = NULL; + if (!render_directly_to_web_view) { + WebKit::WebGraphicsContext3D* view_context = + web_view->graphicsContext3D(); + if (view_context) { + WebGraphicsContext3DInProcessCommandBufferImpl* context_impl = + static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>( + view_context); + parent_context = context_impl->context_; + } } - isScissorEnabled = glIsEnabled(GL_SCISSOR_TEST); - glDisable(GL_SCISSOR_TEST); - isDitherEnabled = glIsEnabled(GL_DITHER); - glDisable(GL_DITHER); - - glClear(clearMask); - - glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); - glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); - if (attributes_.depth) { - glClearDepth(clearDepth); - glDepthMask(depthMask); + + context_ = GLInProcessContext::CreateOffscreenContext( + parent_context, + gfx::Size(1, 1), + preferred_extensions, + attribs, + active_url); + web_view_ = NULL; + + if (!context_) + return false; + + gl_ = context_->GetImplementation(); + context_->SetContextLostCallback( + NewCallback( + this, + &WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost)); + + // Set attributes_ from created offscreen context. + { + attributes_ = attributes; + GLint alpha_bits = 0; + getIntegerv(GL_ALPHA_BITS, &alpha_bits); + attributes_.alpha = alpha_bits > 0; + GLint depth_bits = 0; + getIntegerv(GL_DEPTH_BITS, &depth_bits); + attributes_.depth = depth_bits > 0; + GLint stencil_bits = 0; + getIntegerv(GL_STENCIL_BITS, &stencil_bits); + attributes_.stencil = stencil_bits > 0; + GLint samples = 0; + getIntegerv(GL_SAMPLES, &samples); + attributes_.antialias = samples > 0; } - if (attributes_.stencil) { - glClearStencil(clearStencil); - glStencilMaskSeparate(GL_FRONT, stencilMask); + makeContextCurrent(); + + fprintf(stderr, "Running command buffer\n"); + + return true; +} + +bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() { + return GLInProcessContext::MakeCurrent(context_); +} + +void WebGraphicsContext3DInProcessCommandBufferImpl::ClearContext() { + // NOTE: Comment in the line below to check for code that is not calling + // eglMakeCurrent where appropriate. The issue is code using + // WebGraphicsContext3D does not need to call makeContextCurrent. Code using + // direct OpenGL bindings needs to call the appropriate form of + // eglMakeCurrent. If it doesn't it will be issuing commands on the wrong + // context. Uncommenting the line below clears the current context so that + // any code not calling eglMakeCurrent in the appropriate place should crash. + // This is not a perfect test but generally code that used the direct OpenGL + // bindings should not be mixed with code that uses WebGraphicsContext3D. + // + // GLInProcessContext::MakeCurrent(NULL); +} + +int WebGraphicsContext3DInProcessCommandBufferImpl::width() { + return cached_width_; +} + +int WebGraphicsContext3DInProcessCommandBufferImpl::height() { + return cached_height_; +} + +bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() { + return true; +} + +WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() { + DCHECK(context_); + return context_->GetParentTextureId(); +} + +void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() { + // Copies the contents of the off-screen render target into the texture + // used by the compositor. + context_->SwapBuffers(); +} + +void WebGraphicsContext3DInProcessCommandBufferImpl::reshape( + int width, int height) { + cached_width_ = width; + cached_height_ = height; + + // TODO(gmam): See if we can comment this in. + // ClearContext(); + + if (web_view_) { +#if defined(OS_MACOSX) + context_->ResizeOnscreen(gfx::Size(width, height)); +#else + gl_->ResizeCHROMIUM(width, height); +#endif + } else { + context_->ResizeOffscreen(gfx::Size(width, height)); + // Force a SwapBuffers to get the framebuffer to resize. + context_->SwapBuffers(); } - if (isScissorEnabled) - glEnable(GL_SCISSOR_TEST); - else - glDisable(GL_SCISSOR_TEST); - if (isDitherEnabled) - glEnable(GL_DITHER); - else - glDisable(GL_DITHER); - - if (must_restore_fbo) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); #ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (scanline_) { - delete[] scanline_; - scanline_ = 0; - } - scanline_ = new unsigned char[width * 4]; + scanline_.reset(new uint8[width * 4]); #endif // FLIP_FRAMEBUFFER_VERTICALLY } +WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createCompositorTexture( + WGC3Dsizei width, WGC3Dsizei height) { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + return context_->CreateParentTexture(gfx::Size(width, height)); +} + +void WebGraphicsContext3DInProcessCommandBufferImpl::deleteCompositorTexture( + WebGLId parent_texture) { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + context_->DeleteParentTexture(parent_texture); +} + #ifdef FLIP_FRAMEBUFFER_VERTICALLY void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically( - unsigned char* framebuffer, unsigned int width, unsigned int height) { - unsigned char* scanline = scanline_; + uint8* framebuffer, + unsigned int width, + unsigned int height) { + uint8* scanline = scanline_.get(); if (!scanline) return; unsigned int row_bytes = width * 4; unsigned int count = height / 2; for (unsigned int i = 0; i < count; i++) { - unsigned char* row_a = framebuffer + i * row_bytes; - unsigned char* row_b = framebuffer + (height - i - 1) * row_bytes; - // FIXME: this is where the multiplication of the alpha + uint8* row_a = framebuffer + i * row_bytes; + uint8* row_b = framebuffer + (height - i - 1) * row_bytes; + // TODO(kbr): this is where the multiplication of the alpha // channel into the color buffer will need to occur if the // user specifies the "premultiplyAlpha" flag in the context // creation attributes. @@ -581,11 +919,13 @@ void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically( #endif bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( - unsigned char* pixels, size_t bufferSize) { - if (bufferSize != static_cast<size_t>(4 * width() * height())) + unsigned char* pixels, + size_t buffer_size) { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + if (buffer_size != static_cast<size_t>(4 * width() * height())) { return false; - - makeContextCurrent(); + } // Earlier versions of this code used the GPU to flip the // framebuffer vertically before reading it back for compositing @@ -594,263 +934,276 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( // vertical flip is only a temporary solution anyway until Chrome // is fully GPU composited, it wasn't worth the complexity. - ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - - GLint pack_alignment = 4; - bool must_restore_pack_alignment = false; - glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment); - if (pack_alignment > 4) { - glPixelStorei(GL_PACK_ALIGNMENT, 4); - must_restore_pack_alignment = true; + bool mustRestoreFBO = (bound_fbo_ != 0); + if (mustRestoreFBO) { + gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); } + gl_->ReadPixels(0, 0, cached_width_, cached_height_, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); - if (is_gles2_) { - // FIXME: consider testing for presence of GL_OES_read_format - // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here - // directly. - glReadPixels(0, 0, cached_width_, cached_height_, - GL_RGBA, GL_UNSIGNED_BYTE, pixels); - for (size_t i = 0; i < bufferSize; i += 4) { - std::swap(pixels[i], pixels[i + 2]); - } - } else { - glReadPixels(0, 0, cached_width_, cached_height_, - GL_BGRA, GL_UNSIGNED_BYTE, pixels); + // Swizzle red and blue channels + // TODO(kbr): expose GL_BGRA as extension + for (size_t i = 0; i < buffer_size; i += 4) { + std::swap(pixels[i], pixels[i + 2]); } - if (must_restore_pack_alignment) - glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); + if (mustRestoreFBO) { + gl_->BindFramebuffer(GL_FRAMEBUFFER, bound_fbo_); + } #ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (pixels) + if (pixels) { FlipVertically(pixels, cached_width_, cached_height_); + } #endif return true; } -void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError(WGC3Denum error) { - if (synthetic_errors_set_.find(error) == synthetic_errors_set_.end()) { - synthetic_errors_set_.insert(error); - synthetic_errors_list_.push_back(error); +void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError( + WGC3Denum error) { + if (find(synthetic_errors_.begin(), synthetic_errors_.end(), error) == + synthetic_errors_.end()) { + synthetic_errors_.push_back(error); } } void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferSubDataCHROMIUM( - WGC3Denum target, WGC3Dintptr offset, - WGC3Dsizeiptr size, WGC3Denum access) { - return 0; + WGC3Denum target, + WGC3Dintptr offset, + WGC3Dsizeiptr size, + WGC3Denum access) { + ClearContext(); + return gl_->MapBufferSubDataCHROMIUM(target, offset, size, access); } void WebGraphicsContext3DInProcessCommandBufferImpl::unmapBufferSubDataCHROMIUM( const void* mem) { + ClearContext(); + return gl_->UnmapBufferSubDataCHROMIUM(mem); } void* WebGraphicsContext3DInProcessCommandBufferImpl::mapTexSubImage2DCHROMIUM( - WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, - WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type, + WGC3Denum target, + WGC3Dint level, + WGC3Dint xoffset, + WGC3Dint yoffset, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Denum format, + WGC3Denum type, WGC3Denum access) { - return 0; + ClearContext(); + return gl_->MapTexSubImage2DCHROMIUM( + target, level, xoffset, yoffset, width, height, format, type, access); } void WebGraphicsContext3DInProcessCommandBufferImpl::unmapTexSubImage2DCHROMIUM( const void* mem) { + ClearContext(); + gl_->UnmapTexSubImage2DCHROMIUM(mem); } -void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToParentTextureCHROMIUM( - WebGLId id, WebGLId id2) { - if (!glGetTexLevelParameteriv) - return; +void WebGraphicsContext3DInProcessCommandBufferImpl:: + copyTextureToParentTextureCHROMIUM(WebGLId texture, WebGLId parentTexture) { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + copyTextureToCompositor(texture, parentTexture); +} - makeContextCurrent(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, copy_texture_to_parent_texture_fbo_); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - id, - 0); // level - glBindTexture(GL_TEXTURE_2D, id2); - GLsizei width, height; - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); - glCopyTexImage2D(GL_TEXTURE_2D, - 0, // level - GL_RGBA, - 0, 0, // x, y - width, - height, - 0); // border - glBindTexture(GL_TEXTURE_2D, bound_texture_); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); -} - -void WebGraphicsContext3DInProcessCommandBufferImpl::getParentToChildLatchCHROMIUM( - WGC3Duint* latch_id) +void WebGraphicsContext3DInProcessCommandBufferImpl:: + getParentToChildLatchCHROMIUM(WGC3Duint* latch_id) { + ClearContext(); + if (!context_->GetParentToChildLatch(latch_id)) { + LOG(ERROR) << "getLatch must only be called on child context"; + synthesizeGLError(GL_INVALID_OPERATION); + *latch_id = ::gpu::kInvalidLatchId; + } } -void WebGraphicsContext3DInProcessCommandBufferImpl::getChildToParentLatchCHROMIUM( - WGC3Duint* latch_id) +void WebGraphicsContext3DInProcessCommandBufferImpl:: + getChildToParentLatchCHROMIUM(WGC3Duint* latch_id) { + ClearContext(); + if (!context_->GetChildToParentLatch(latch_id)) { + LOG(ERROR) << "getLatch must only be called on child context"; + synthesizeGLError(GL_INVALID_OPERATION); + *latch_id = ::gpu::kInvalidLatchId; + } } void WebGraphicsContext3DInProcessCommandBufferImpl::waitLatchCHROMIUM( WGC3Duint latch_id) { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + gl_->WaitLatchCHROMIUM(latch_id); } void WebGraphicsContext3DInProcessCommandBufferImpl::setLatchCHROMIUM( WGC3Duint latch_id) { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + gl_->SetLatchCHROMIUM(latch_id); + // required to ensure set command is sent to GPU process + gl_->Flush(); +} + +void WebGraphicsContext3DInProcessCommandBufferImpl:: + rateLimitOffscreenContextCHROMIUM() { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + gl_->RateLimitOffscreenContextCHROMIUM(); } -WebString WebGraphicsContext3DInProcessCommandBufferImpl:: +WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: getRequestableExtensionsCHROMIUM() { - return WebString(); + // TODO(gmam): See if we can comment this in. + // ClearContext(); + return WebKit::WebString::fromUTF8( + gl_->GetRequestableExtensionsCHROMIUM()); } -void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM(const char*) { +void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM( + const char* extension) { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + gl_->RequestExtensionCHROMIUM(extension); } void WebGraphicsContext3DInProcessCommandBufferImpl::blitFramebufferCHROMIUM( WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, WGC3Dbitfield mask, WGC3Denum filter) { + ClearContext(); + gl_->BlitFramebufferEXT( + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); } -void WebGraphicsContext3DInProcessCommandBufferImpl::renderbufferStorageMultisampleCHROMIUM( - WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, - WGC3Dsizei width, WGC3Dsizei height) { +void WebGraphicsContext3DInProcessCommandBufferImpl:: + renderbufferStorageMultisampleCHROMIUM( + WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, + WGC3Dsizei width, WGC3Dsizei height) { + ClearContext(); + gl_->RenderbufferStorageMultisampleEXT( + target, samples, internalformat, width, height); } // Helper macros to reduce the amount of code. -#define DELEGATE_TO_GL(name, glname) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name() { \ - makeContextCurrent(); \ - gl##glname(); \ +#define DELEGATE_TO_GL(name, glname) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name() { \ + ClearContext(); \ + gl_->glname(); \ } -#define DELEGATE_TO_GL_1(name, glname, t1) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ - makeContextCurrent(); \ - gl##glname(a1); \ +#define DELEGATE_TO_GL_1(name, glname, t1) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ + ClearContext(); \ + gl_->glname(a1); \ } -#define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ -rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ - makeContextCurrent(); \ - return gl##glname(a1); \ +#define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ +rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ + ClearContext(); \ + return gl_->glname(a1); \ } -#define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ -rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ - makeContextCurrent(); \ - return gl##glname(a1) ? true : false; \ +#define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ +rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ + ClearContext(); \ + return gl_->glname(a1) ? true : false; \ } -#define DELEGATE_TO_GL_2(name, glname, t1, t2) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ - makeContextCurrent(); \ - gl##glname(a1, a2); \ +#define DELEGATE_TO_GL_2(name, glname, t1, t2) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ + t1 a1, t2 a2) { \ + ClearContext(); \ + gl_->glname(a1, a2); \ } -#define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ -rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ - makeContextCurrent(); \ - return gl##glname(a1, a2); \ +#define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ +rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ + ClearContext(); \ + return gl_->glname(a1, a2); \ } -#define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3); \ +#define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ + t1 a1, t2 a2, t3 a3) { \ + ClearContext(); \ + gl_->glname(a1, a2, a3); \ } -#define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t4 a4) { \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4); \ +#define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ + t1 a1, t2 a2, t3 a3, t4 a4) { \ + ClearContext(); \ + gl_->glname(a1, a2, a3, a4); \ } -#define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \ - t5 a5) { \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5); \ +#define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ + t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { \ + ClearContext(); \ + gl_->glname(a1, a2, a3, a4, a5); \ } -#define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \ - t5 a5, t6 a6) { \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5, a6); \ +#define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ + t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \ + ClearContext(); \ + gl_->glname(a1, a2, a3, a4, a5, a6); \ } -#define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \ - t5 a5, t6 a6, t7 a7) { \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5, a6, a7); \ +#define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ + t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) { \ + ClearContext(); \ + gl_->glname(a1, a2, a3, a4, a5, a6, a7); \ } -#define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \ - t5 a5, t6 a6, t7 a7, t8 a8) { \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \ +#define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ + t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) { \ + ClearContext(); \ + gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8); \ } -#define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ -void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \ - t5 a5, t6 a6, t7 a7, t8 a8, \ - t9 a9) { \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ +#define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ +void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ + t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) { \ + ClearContext(); \ + gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ } -void WebGraphicsContext3DInProcessCommandBufferImpl::activeTexture(WGC3Denum texture) { - // FIXME: query number of textures available. - if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) - // FIXME: raise exception. - return; - - makeContextCurrent(); - glActiveTexture(texture); -} +DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum) DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) -DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, - WebGLId, WGC3Duint, const WGC3Dchar*) +DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId, + WGC3Duint, const WGC3Dchar*) -DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId); +DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId) void WebGraphicsContext3DInProcessCommandBufferImpl::bindFramebuffer( - WGC3Denum target, WebGLId framebuffer) { - makeContextCurrent(); - if (!framebuffer) - framebuffer = (attributes_.antialias ? multisample_fbo_ : fbo_); - if (framebuffer != bound_fbo_) { - glBindFramebufferEXT(target, framebuffer); - bound_fbo_ = framebuffer; - } + WGC3Denum target, + WebGLId framebuffer) { + ClearContext(); + gl_->BindFramebuffer(target, framebuffer); + bound_fbo_ = framebuffer; } -DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbufferEXT, WGC3Denum, WebGLId) +DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId) -void WebGraphicsContext3DInProcessCommandBufferImpl::bindTexture( - WGC3Denum target, WebGLId texture) { - makeContextCurrent(); - glBindTexture(target, texture); - bound_texture_ = texture; -} +DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId) DELEGATE_TO_GL_4(blendColor, BlendColor, - WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) + WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum) @@ -868,7 +1221,7 @@ DELEGATE_TO_GL_4(bufferData, BufferData, DELEGATE_TO_GL_4(bufferSubData, BufferSubData, WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*) -DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatusEXT, +DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus, WGC3Denum, WGC3Denum) DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield) @@ -876,79 +1229,22 @@ DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield) DELEGATE_TO_GL_4(clearColor, ClearColor, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) -DELEGATE_TO_GL_1(clearDepth, ClearDepth, WGC3Dclampf) +DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf) DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint) DELEGATE_TO_GL_4(colorMask, ColorMask, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean) -void WebGraphicsContext3DInProcessCommandBufferImpl::compileShader(WebGLId shader) { - makeContextCurrent(); - - ShaderSourceMap::iterator result = shader_source_map_.find(shader); - if (result == shader_source_map_.end()) { - // Passing down to gl driver to generate the correct error; or the case - // where the shader deletion is delayed when it's attached to a program. - glCompileShader(shader); - return; - } - ShaderSourceEntry* entry = result->second; - DCHECK(entry); - - if (!AngleValidateShaderSource(entry)) { - // Shader didn't validate; don't move forward with compiling - // translated source. - return; - } - - const char* translated_source = entry->translated_source.get(); - int shader_length = translated_source ? strlen(translated_source) : 0; - glShaderSource( - shader, 1, const_cast<const char**>(&translated_source), &shader_length); - glCompileShader(shader); - -#ifndef NDEBUG - int compileStatus; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); - // DCHECK that ANGLE generated GLSL will be accepted by OpenGL - DCHECK(compileStatus == GL_TRUE); -#endif -} - -void WebGraphicsContext3DInProcessCommandBufferImpl::copyTexImage2D( - WGC3Denum target, WGC3Dint level, WGC3Denum internalformat, WGC3Dint x, - WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border) { - makeContextCurrent(); - - bool needsResolve = (attributes_.antialias && bound_fbo_ == multisample_fbo_); - if (needsResolve) { - ResolveMultisampledFramebuffer(x, y, width, height); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - } - - glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); - - if (needsResolve) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); -} - -void WebGraphicsContext3DInProcessCommandBufferImpl::copyTexSubImage2D( - WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, - WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) { - makeContextCurrent(); +DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId) - bool needsResolve = (attributes_.antialias && bound_fbo_ == multisample_fbo_); - if (needsResolve) { - ResolveMultisampledFramebuffer(x, y, width, height); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - } - - glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D, + WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, + WGC3Dsizei, WGC3Dsizei, WGC3Dint) - if (needsResolve) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); -} +DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D, + WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, + WGC3Dsizei, WGC3Dsizei) DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum) @@ -956,69 +1252,73 @@ DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum) DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean) -DELEGATE_TO_GL_2(depthRange, DepthRange, WGC3Dclampf, WGC3Dclampf) +DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf) DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) DELEGATE_TO_GL_1(disable, Disable, WGC3Denum) -DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, WGC3Duint) +DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, + WGC3Duint) DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei) void WebGraphicsContext3DInProcessCommandBufferImpl::drawElements( - WGC3Denum mode, WGC3Dsizei count, WGC3Denum type, WGC3Dintptr offset) { - makeContextCurrent(); - glDrawElements(mode, count, type, - reinterpret_cast<void*>(static_cast<intptr_t>(offset))); + WGC3Denum mode, + WGC3Dsizei count, + WGC3Denum type, + WGC3Dintptr offset) { + ClearContext(); + gl_->DrawElements( + mode, count, type, + reinterpret_cast<void*>(static_cast<intptr_t>(offset))); } DELEGATE_TO_GL_1(enable, Enable, WGC3Denum) -DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, WGC3Duint) +DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, + WGC3Duint) DELEGATE_TO_GL(finish, Finish) DELEGATE_TO_GL(flush, Flush) -DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbufferEXT, +DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer, WGC3Denum, WGC3Denum, WGC3Denum, WebGLId) -DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT, +DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D, WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint) DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum) -void WebGraphicsContext3DInProcessCommandBufferImpl::generateMipmap(WGC3Denum target) { - makeContextCurrent(); - if (is_gles2_ || have_ext_framebuffer_object_) - glGenerateMipmapEXT(target); - // FIXME: provide alternative code path? This will be unpleasant - // to implement if glGenerateMipmapEXT is not available -- it will - // require a texture readback and re-upload. -} +DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum) bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveAttrib( WebGLId program, WGC3Duint index, ActiveInfo& info) { - makeContextCurrent(); + ClearContext(); if (!program) { synthesizeGLError(GL_INVALID_VALUE); return false; } GLint max_name_length = -1; - glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); + gl_->GetProgramiv( + program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); if (max_name_length < 0) return false; scoped_array<GLchar> name(new GLchar[max_name_length]); + if (!name.get()) { + synthesizeGLError(GL_OUT_OF_MEMORY); + return false; + } GLsizei length = 0; GLint size = -1; GLenum type = 0; - glGetActiveAttrib(program, index, max_name_length, - &length, &size, &type, name.get()); + gl_->GetActiveAttrib( + program, index, max_name_length, &length, &size, &type, name.get()); if (size < 0) { return false; } - info.name = WebString::fromUTF8(name.get(), length); + info.name = WebKit::WebString::fromUTF8(name.get(), length); info.type = type; info.size = size; return true; @@ -1026,21 +1326,26 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveAttrib( bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveUniform( WebGLId program, WGC3Duint index, ActiveInfo& info) { - makeContextCurrent(); + ClearContext(); GLint max_name_length = -1; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); + gl_->GetProgramiv( + program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); if (max_name_length < 0) return false; scoped_array<GLchar> name(new GLchar[max_name_length]); + if (!name.get()) { + synthesizeGLError(GL_OUT_OF_MEMORY); + return false; + } GLsizei length = 0; GLint size = -1; GLenum type = 0; - glGetActiveUniform(program, index, max_name_length, - &length, &size, &type, name.get()); + gl_->GetActiveUniform( + program, index, max_name_length, &length, &size, &type, name.get()); if (size < 0) { return false; } - info.name = WebString::fromUTF8(name.get(), length); + info.name = WebKit::WebString::fromUTF8(name.get(), length); info.type = type; info.size = size; return true; @@ -1052,195 +1357,109 @@ DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, WebGLId, const WGC3Dchar*, WGC3Dint) -DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, - WGC3Denum, WGC3Dboolean*) +DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*) DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, WGC3Denum, WGC3Denum, WGC3Dint*) -WebGraphicsContext3D::Attributes WebGraphicsContext3DInProcessCommandBufferImpl:: - getContextAttributes() { +WebKit::WebGraphicsContext3D::Attributes +WebGraphicsContext3DInProcessCommandBufferImpl::getContextAttributes() { return attributes_; } WGC3Denum WebGraphicsContext3DInProcessCommandBufferImpl::getError() { - DCHECK(synthetic_errors_list_.size() == synthetic_errors_set_.size()); - if (!synthetic_errors_set_.empty()) { - WGC3Denum error = synthetic_errors_list_.front(); - synthetic_errors_list_.pop_front(); - synthetic_errors_set_.erase(error); - return error; + ClearContext(); + if (!synthetic_errors_.empty()) { + std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin(); + WGC3Denum err = *iter; + synthetic_errors_.erase(iter); + return err; } - makeContextCurrent(); - return glGetError(); + return gl_->GetError(); } bool WebGraphicsContext3DInProcessCommandBufferImpl::isContextLost() { - return false; + return context_->IsCommandBufferContextLost(); } DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) -void WebGraphicsContext3DInProcessCommandBufferImpl::getFramebufferAttachmentParameteriv( - WGC3Denum target, WGC3Denum attachment, - WGC3Denum pname, WGC3Dint* value) { - makeContextCurrent(); - if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) - attachment = GL_DEPTH_ATTACHMENT; // Or GL_STENCIL_ATTACHMENT; - // either works. - glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); -} +DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv, + GetFramebufferAttachmentParameteriv, + WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*) -void WebGraphicsContext3DInProcessCommandBufferImpl::getIntegerv( - WGC3Denum pname, WGC3Dint* value) { - makeContextCurrent(); - if (is_gles2_) { - glGetIntegerv(pname, value); - return; - } - // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and - // MAX_VARYING_VECTORS because desktop GL's corresponding queries - // return the number of components whereas GLES2 return the number - // of vectors (each vector has 4 components). Therefore, the value - // returned by desktop GL needs to be divided by 4. - switch (pname) { - case MAX_FRAGMENT_UNIFORM_VECTORS: - glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); - *value /= 4; - break; - case MAX_VERTEX_UNIFORM_VECTORS: - glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value); - *value /= 4; - break; - case MAX_VARYING_VECTORS: - glGetIntegerv(GL_MAX_VARYING_FLOATS, value); - *value /= 4; - break; - default: - glGetIntegerv(pname, value); - } -} +DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*) DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*) -WebString WebGraphicsContext3DInProcessCommandBufferImpl::getProgramInfoLog( - WebGLId program) { - makeContextCurrent(); - GLint log_length; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length); - if (!log_length) - return WebString(); - scoped_array<GLchar> log(new GLchar[log_length]); - GLsizei returned_log_length; - glGetProgramInfoLog(program, log_length, &returned_log_length, log.get()); - DCHECK(log_length == returned_log_length + 1); - WebString res = WebString::fromUTF8(log.get(), returned_log_length); +WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: + getProgramInfoLog(WebGLId program) { + ClearContext(); + GLint logLength = 0; + gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); + if (!logLength) + return WebKit::WebString(); + scoped_array<GLchar> log(new GLchar[logLength]); + if (!log.get()) + return WebKit::WebString(); + GLsizei returnedLogLength = 0; + gl_->GetProgramInfoLog( + program, logLength, &returnedLogLength, log.get()); + DCHECK_EQ(logLength, returnedLogLength + 1); + WebKit::WebString res = + WebKit::WebString::fromUTF8(log.get(), returnedLogLength); return res; } -DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameterivEXT, +DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv, WGC3Denum, WGC3Denum, WGC3Dint*) -void WebGraphicsContext3DInProcessCommandBufferImpl::getShaderiv( - WebGLId shader, WGC3Denum pname, WGC3Dint* value) { - makeContextCurrent(); - - ShaderSourceMap::iterator result = shader_source_map_.find(shader); - if (result != shader_source_map_.end()) { - ShaderSourceEntry* entry = result->second; - DCHECK(entry); - switch (pname) { - case GL_COMPILE_STATUS: - if (!entry->is_valid) { - *value = 0; - return; - } - break; - case GL_INFO_LOG_LENGTH: - if (!entry->is_valid) { - *value = entry->log.get() ? strlen(entry->log.get()) : 0; - if (*value) - (*value)++; - return; - } - break; - case GL_SHADER_SOURCE_LENGTH: - *value = entry->source.get() ? strlen(entry->source.get()) : 0; - if (*value) - (*value)++; - return; - } - } - - glGetShaderiv(shader, pname, value); -} - -WebString WebGraphicsContext3DInProcessCommandBufferImpl::getShaderInfoLog(WebGLId shader) { - makeContextCurrent(); - - ShaderSourceMap::iterator result = shader_source_map_.find(shader); - if (result != shader_source_map_.end()) { - ShaderSourceEntry* entry = result->second; - DCHECK(entry); - if (!entry->is_valid) { - if (!entry->log.get()) - return WebString(); - WebString res = WebString::fromUTF8( - entry->log.get(), strlen(entry->log.get())); - return res; - } - } - - GLint log_length = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); - if (log_length <= 1) - return WebString(); - scoped_array<GLchar> log(new GLchar[log_length]); - GLsizei returned_log_length; - glGetShaderInfoLog(shader, log_length, &returned_log_length, log.get()); - DCHECK(log_length == returned_log_length + 1); - WebString res = WebString::fromUTF8(log.get(), returned_log_length); +DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*) + +WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: + getShaderInfoLog(WebGLId shader) { + ClearContext(); + GLint logLength = 0; + gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); + if (!logLength) + return WebKit::WebString(); + scoped_array<GLchar> log(new GLchar[logLength]); + if (!log.get()) + return WebKit::WebString(); + GLsizei returnedLogLength = 0; + gl_->GetShaderInfoLog( + shader, logLength, &returnedLogLength, log.get()); + DCHECK_EQ(logLength, returnedLogLength + 1); + WebKit::WebString res = + WebKit::WebString::fromUTF8(log.get(), returnedLogLength); return res; } -WebString WebGraphicsContext3DInProcessCommandBufferImpl::getShaderSource(WebGLId shader) { - makeContextCurrent(); - - ShaderSourceMap::iterator result = shader_source_map_.find(shader); - if (result != shader_source_map_.end()) { - ShaderSourceEntry* entry = result->second; - DCHECK(entry); - if (!entry->source.get()) - return WebString(); - WebString res = WebString::fromUTF8( - entry->source.get(), strlen(entry->source.get())); - return res; - } - - GLint log_length = 0; - glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &log_length); - if (log_length <= 1) - return WebString(); - scoped_array<GLchar> log(new GLchar[log_length]); - GLsizei returned_log_length; - glGetShaderSource(shader, log_length, &returned_log_length, log.get()); - DCHECK(log_length == returned_log_length + 1); - WebString res = WebString::fromUTF8(log.get(), returned_log_length); +WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: + getShaderSource(WebGLId shader) { + ClearContext(); + GLint logLength = 0; + gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength); + if (!logLength) + return WebKit::WebString(); + scoped_array<GLchar> log(new GLchar[logLength]); + if (!log.get()) + return WebKit::WebString(); + GLsizei returnedLogLength = 0; + gl_->GetShaderSource( + shader, logLength, &returnedLogLength, log.get()); + DCHECK_EQ(logLength, returnedLogLength + 1); + WebKit::WebString res = + WebKit::WebString::fromUTF8(log.get(), returnedLogLength); return res; } -WebString WebGraphicsContext3DInProcessCommandBufferImpl::getString(WGC3Denum name) { - makeContextCurrent(); - std::string result(reinterpret_cast<const char*>(glGetString(name))); - if (name == GL_EXTENSIONS) { - // GL_CHROMIUM_copy_texture_to_parent_texture requires the - // desktopGL-only function glGetTexLevelParameteriv (GLES2 - // doesn't support it). - if (!is_gles2_) - result += " GL_CHROMIUM_copy_texture_to_parent_texture"; - } - return WebString::fromUTF8(result.c_str()); +WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::getString( + WGC3Denum name) { + ClearContext(); + return WebKit::WebString::fromUTF8( + reinterpret_cast<const char*>(gl_->GetString(name))); } DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, @@ -1262,12 +1481,14 @@ DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, WGC3Duint, WGC3Denum, WGC3Dint*) -WGC3Dsizeiptr WebGraphicsContext3DInProcessCommandBufferImpl::getVertexAttribOffset( - WGC3Duint index, WGC3Denum pname) { - makeContextCurrent(); - void* pointer; - glGetVertexAttribPointerv(index, pname, &pointer); - return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer)); +WGC3Dsizeiptr WebGraphicsContext3DInProcessCommandBufferImpl:: + getVertexAttribOffset(WGC3Duint index, WGC3Denum pname) { + ClearContext(); + GLvoid* value = NULL; + // NOTE: If pname is ever a value that returns more then 1 element + // this will corrupt memory. + gl_->GetVertexAttribPointerv(index, pname, &value); + return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value)); } DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum) @@ -1276,11 +1497,11 @@ DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean) DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean) -DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebufferEXT, WebGLId, WGC3Dboolean) +DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean) DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean) -DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbufferEXT, WebGLId, WGC3Dboolean) +DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean) DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean) @@ -1294,86 +1515,26 @@ DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint) DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat) -void WebGraphicsContext3DInProcessCommandBufferImpl::readPixels( - WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height, - WGC3Denum format, WGC3Denum type, void* pixels) { - makeContextCurrent(); - // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., - // all previous rendering calls should be done before reading pixels. - glFlush(); - bool needs_resolve = - (attributes_.antialias && bound_fbo_ == multisample_fbo_); - if (needs_resolve) { - ResolveMultisampledFramebuffer(x, y, width, height); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - glFlush(); - } - - glReadPixels(x, y, width, height, format, type, pixels); - - if (needs_resolve) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); -} +DELEGATE_TO_GL_7(readPixels, ReadPixels, + WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum, + WGC3Denum, void*) void WebGraphicsContext3DInProcessCommandBufferImpl::releaseShaderCompiler() { + ClearContext(); } -void WebGraphicsContext3DInProcessCommandBufferImpl::renderbufferStorage( - WGC3Denum target, - WGC3Denum internalformat, - WGC3Dsizei width, - WGC3Dsizei height) { - makeContextCurrent(); - if (!is_gles2_) { - switch (internalformat) { - case GL_DEPTH_STENCIL: - internalformat = GL_DEPTH24_STENCIL8_EXT; - break; - case GL_DEPTH_COMPONENT16: - internalformat = GL_DEPTH_COMPONENT; - break; - case GL_RGBA4: - case GL_RGB5_A1: - internalformat = GL_RGBA; - break; - case 0x8D62: // GL_RGB565 - internalformat = GL_RGB; - break; - } - } - glRenderbufferStorageEXT(target, internalformat, width, height); -} +DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage, + WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei) -DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dclampf, WGC3Dboolean) +DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean) DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) -void WebGraphicsContext3DInProcessCommandBufferImpl::texImage2D( - WGC3Denum target, WGC3Dint level, WGC3Denum internalFormat, - WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, - WGC3Denum format, WGC3Denum type, const void* pixels) { - if (width && height && !pixels) { - synthesizeGLError(GL_INVALID_VALUE); - return; - } - makeContextCurrent(); - glTexImage2D(target, level, internalFormat, - width, height, border, format, type, pixels); -} - void WebGraphicsContext3DInProcessCommandBufferImpl::shaderSource( - WebGLId shader, const WGC3Dchar* source) { - makeContextCurrent(); - GLint length = source ? strlen(source) : 0; - ShaderSourceMap::iterator result = shader_source_map_.find(shader); - if (result != shader_source_map_.end()) { - ShaderSourceEntry* entry = result->second; - DCHECK(entry); - entry->source.reset(new char[length + 1]); - memcpy(entry->source.get(), source, (length + 1) * sizeof(char)); - } else { - glShaderSource(shader, 1, &source, &length); - } + WebGLId shader, const WGC3Dchar* string) { + ClearContext(); + GLint length = strlen(string); + gl_->ShaderSource(shader, 1, &string, &length); } DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint) @@ -1392,9 +1553,27 @@ DELEGATE_TO_GL_3(stencilOp, StencilOp, DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) -DELEGATE_TO_GL_3(texParameterf, TexParameterf, WGC3Denum, WGC3Denum, WGC3Dfloat) +DELEGATE_TO_GL_9(texImage2D, TexImage2D, + WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, + WGC3Dint, WGC3Denum, WGC3Denum, const void*) + +DELEGATE_TO_GL_3(texParameterf, TexParameterf, + WGC3Denum, WGC3Denum, WGC3Dfloat); + +static const unsigned int kTextureWrapR = 0x8072; -DELEGATE_TO_GL_3(texParameteri, TexParameteri, WGC3Denum, WGC3Denum, WGC3Dint) +void WebGraphicsContext3DInProcessCommandBufferImpl::texParameteri( + WGC3Denum target, WGC3Denum pname, WGC3Dint param) { + ClearContext(); + // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in + // GraphicsContext3D.cpp is strictly necessary to avoid seams at the + // edge of cube maps, and, if it is, push it into the GLES2 service + // side code. + if (pname == kTextureWrapR) { + return; + } + gl_->TexParameteri(target, pname, param); +} DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, @@ -1402,8 +1581,8 @@ DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat) -DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, - WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) +DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei, + const WGC3Dfloat*) DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint) @@ -1411,18 +1590,18 @@ DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat) -DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, - WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) +DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei, + const WGC3Dfloat*) DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint) DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) -DELEGATE_TO_GL_4(uniform3f, Uniform3f, - WGC3Dint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) +DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint, + WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) -DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, - WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) +DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei, + const WGC3Dfloat*) DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) @@ -1431,8 +1610,8 @@ DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) -DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, - WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) +DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei, + const WGC3Dfloat*) DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) @@ -1454,209 +1633,135 @@ DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat) -DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, const WGC3Dfloat*) +DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, + const WGC3Dfloat*) -DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, - WGC3Duint, WGC3Dfloat, WGC3Dfloat) +DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint, + WGC3Dfloat, WGC3Dfloat) -DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, const WGC3Dfloat*) +DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, + const WGC3Dfloat*) -DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, - WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) +DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint, + WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) -DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, const WGC3Dfloat*) +DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, + const WGC3Dfloat*) -DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, - WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) +DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint, + WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) -DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, const WGC3Dfloat*) +DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, + const WGC3Dfloat*) void WebGraphicsContext3DInProcessCommandBufferImpl::vertexAttribPointer( WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized, WGC3Dsizei stride, WGC3Dintptr offset) { - makeContextCurrent(); - glVertexAttribPointer(index, size, type, normalized, stride, - reinterpret_cast<void*>(static_cast<intptr_t>(offset))); + ClearContext(); + gl_->VertexAttribPointer( + index, size, type, normalized, stride, + reinterpret_cast<void*>(static_cast<intptr_t>(offset))); } -DELEGATE_TO_GL_4(viewport, Viewport, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) +DELEGATE_TO_GL_4(viewport, Viewport, + WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createBuffer() { - makeContextCurrent(); + ClearContext(); GLuint o; - glGenBuffersARB(1, &o); + gl_->GenBuffers(1, &o); return o; } WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createFramebuffer() { - makeContextCurrent(); + ClearContext(); GLuint o = 0; - glGenFramebuffersEXT(1, &o); + gl_->GenFramebuffers(1, &o); return o; } WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createProgram() { - makeContextCurrent(); - return glCreateProgram(); + ClearContext(); + return gl_->CreateProgram(); } WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createRenderbuffer() { - makeContextCurrent(); + ClearContext(); GLuint o; - glGenRenderbuffersEXT(1, &o); + gl_->GenRenderbuffers(1, &o); return o; } -WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createShader( - WGC3Denum shaderType) { - makeContextCurrent(); - DCHECK(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER); - GLuint shader = glCreateShader(shaderType); - if (shader) { - ShaderSourceMap::iterator result = shader_source_map_.find(shader); - if (result != shader_source_map_.end()) { - delete result->second; - shader_source_map_.erase(result); - } - shader_source_map_.insert( - ShaderSourceMap::value_type(shader, new ShaderSourceEntry(shaderType))); - } - - return shader; -} +DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId); WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createTexture() { - makeContextCurrent(); + ClearContext(); GLuint o; - glGenTextures(1, &o); + gl_->GenTextures(1, &o); return o; } -void WebGraphicsContext3DInProcessCommandBufferImpl::deleteBuffer(WebGLId buffer) { - makeContextCurrent(); - glDeleteBuffersARB(1, &buffer); +void WebGraphicsContext3DInProcessCommandBufferImpl::deleteBuffer( + WebGLId buffer) { + ClearContext(); + gl_->DeleteBuffers(1, &buffer); } void WebGraphicsContext3DInProcessCommandBufferImpl::deleteFramebuffer( WebGLId framebuffer) { - makeContextCurrent(); - glDeleteFramebuffersEXT(1, &framebuffer); + ClearContext(); + gl_->DeleteFramebuffers(1, &framebuffer); } -void WebGraphicsContext3DInProcessCommandBufferImpl::deleteProgram(WebGLId program) { - makeContextCurrent(); - glDeleteProgram(program); +void WebGraphicsContext3DInProcessCommandBufferImpl::deleteProgram( + WebGLId program) { + ClearContext(); + gl_->DeleteProgram(program); } void WebGraphicsContext3DInProcessCommandBufferImpl::deleteRenderbuffer( WebGLId renderbuffer) { - makeContextCurrent(); - glDeleteRenderbuffersEXT(1, &renderbuffer); + ClearContext(); + gl_->DeleteRenderbuffers(1, &renderbuffer); } -void WebGraphicsContext3DInProcessCommandBufferImpl::deleteShader(WebGLId shader) { - makeContextCurrent(); - - ShaderSourceMap::iterator result = shader_source_map_.find(shader); - if (result != shader_source_map_.end()) { - delete result->second; - shader_source_map_.erase(result); - } - glDeleteShader(shader); +void WebGraphicsContext3DInProcessCommandBufferImpl::deleteShader( + WebGLId shader) { + ClearContext(); + gl_->DeleteShader(shader); } -void WebGraphicsContext3DInProcessCommandBufferImpl::deleteTexture(WebGLId texture) { - makeContextCurrent(); - glDeleteTextures(1, &texture); +void WebGraphicsContext3DInProcessCommandBufferImpl::deleteTexture( + WebGLId texture) { + ClearContext(); + gl_->DeleteTextures(1, &texture); } -bool WebGraphicsContext3DInProcessCommandBufferImpl::AngleCreateCompilers() { - if (!ShInitialize()) - return false; - - ShBuiltInResources resources; - ShInitBuiltInResources(&resources); - getIntegerv(GL_MAX_VERTEX_ATTRIBS, &resources.MaxVertexAttribs); - getIntegerv(MAX_VERTEX_UNIFORM_VECTORS, &resources.MaxVertexUniformVectors); - getIntegerv(MAX_VARYING_VECTORS, &resources.MaxVaryingVectors); - getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, - &resources.MaxVertexTextureImageUnits); - getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - &resources.MaxCombinedTextureImageUnits); - getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &resources.MaxTextureImageUnits); - getIntegerv(MAX_FRAGMENT_UNIFORM_VECTORS, - &resources.MaxFragmentUniformVectors); - // Always set to 1 for OpenGL ES. - resources.MaxDrawBuffers = 1; - - fragment_compiler_ = ShConstructCompiler( - SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, &resources); - vertex_compiler_ = ShConstructCompiler( - SH_VERTEX_SHADER, SH_WEBGL_SPEC, &resources); - return (fragment_compiler_ && vertex_compiler_); -} - -void WebGraphicsContext3DInProcessCommandBufferImpl::AngleDestroyCompilers() { - if (fragment_compiler_) { - ShDestruct(fragment_compiler_); - fragment_compiler_ = 0; - } - if (vertex_compiler_) { - ShDestruct(vertex_compiler_); - vertex_compiler_ = 0; - } +void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToCompositor( + WebGLId texture, WebGLId parentTexture) { + // TODO(gmam): See if we can comment this in. + // ClearContext(); + gl_->CopyTextureToParentTextureCHROMIUM(texture, parentTexture); + gl_->Flush(); } -bool WebGraphicsContext3DInProcessCommandBufferImpl::AngleValidateShaderSource( - ShaderSourceEntry* entry) { - entry->is_valid = false; - entry->translated_source.reset(); - entry->log.reset(); - - ShHandle compiler = 0; - switch (entry->type) { - case GL_FRAGMENT_SHADER: - compiler = fragment_compiler_; - break; - case GL_VERTEX_SHADER: - compiler = vertex_compiler_; - break; - } - if (!compiler) - return false; +void WebGraphicsContext3DInProcessCommandBufferImpl::OnSwapBuffersComplete() { +} - char* source = entry->source.get(); - if (!ShCompile(compiler, &source, 1, SH_OBJECT_CODE)) { - int logSize = 0; - ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &logSize); - if (logSize > 1) { - entry->log.reset(new char[logSize]); - ShGetInfoLog(compiler, entry->log.get()); - } - return false; - } +void WebGraphicsContext3DInProcessCommandBufferImpl::setContextLostCallback( + WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) +{ + context_lost_callback_ = cb; +} - int length = 0; - if (is_gles2_) { - // ANGLE does not yet have a GLSL ES backend. Therefore if the - // compile succeeds we send the original source down. - length = strlen(entry->source.get()); - if (length > 0) - ++length; // Add null terminator - } else { - ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &length); - } - if (length > 1) { - entry->translated_source.reset(new char[length]); - if (is_gles2_) - strncpy(entry->translated_source.get(), entry->source.get(), length); - else - ShGetObjectCode(compiler, entry->translated_source.get()); +void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() { + if (context_lost_callback_) { + context_lost_callback_->onContextLost(); } - entry->is_valid = true; - return true; } } // namespace gpu } // namespace webkit +#endif // defined(ENABLE_GPU) + diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h index dc51c80..3b6aaa8 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h @@ -4,24 +4,30 @@ #ifndef WEBKIT_GPU_WEBGRAPHICSCONTEXT3D_IN_PROCESS_COMMAND_BUFFER_IMPL_H_ #define WEBKIT_GPU_WEBGRAPHICSCONTEXT3D_IN_PROCESS_COMMAND_BUFFER_IMPL_H_ +#pragma once -#include <list> -#include <set> +#if defined(ENABLE_GPU) -#include "base/hash_tables.h" -#include "base/memory/ref_counted.h" -#include "third_party/angle/include/GLSLANG/ShaderLang.h" +#include <vector> + +#include "base/memory/scoped_ptr.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebGraphicsContext3D.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" +#include "ui/gfx/native_widget_types.h" #if !defined(OS_MACOSX) #define FLIP_FRAMEBUFFER_VERTICALLY #endif -namespace gfx { -class GLContext; -class GLSurface; + +namespace gpu { +namespace gles2 { +class GLES2Implementation; +} } +using WebKit::WebGLId; + using WebKit::WGC3Dchar; using WebKit::WGC3Denum; using WebKit::WGC3Dboolean; @@ -34,28 +40,24 @@ using WebKit::WGC3Dclampf; using WebKit::WGC3Dintptr; using WebKit::WGC3Dsizeiptr; -using WebKit::WebGLId; - -using WebKit::WebString; -using WebKit::WebView; - -using WebKit::WebGraphicsContext3D; - namespace webkit { namespace gpu { -// TODO(gman): This is a copy of WebGraphicsContext3DInProcessImpl. I will -// refactor it to actually use the command buffer. +class GLInProcessContext; -class WebGraphicsContext3DInProcessCommandBufferImpl : public WebGraphicsContext3D { +class WebGraphicsContext3DInProcessCommandBufferImpl + : public WebKit::WebGraphicsContext3D { public: + WebGraphicsContext3DInProcessCommandBufferImpl(); virtual ~WebGraphicsContext3DInProcessCommandBufferImpl(); //---------------------------------------------------------------------- // WebGraphicsContext3D methods - virtual bool initialize( - WebGraphicsContext3D::Attributes attributes, WebView*, bool); + virtual bool initialize(WebGraphicsContext3D::Attributes attributes, + WebKit::WebView*, + bool renderDirectlyToWebView); + virtual bool makeContextCurrent(); virtual int width(); @@ -65,95 +67,61 @@ class WebGraphicsContext3DInProcessCommandBufferImpl : public WebGraphicsContext virtual void reshape(int width, int height); - virtual bool readBackFramebuffer(unsigned char* pixels, size_t bufferSize); + virtual bool readBackFramebuffer(unsigned char* pixels, size_t buffer_size); virtual WebGLId getPlatformTextureId(); virtual void prepareTexture(); - virtual void synthesizeGLError(WGC3Denum error); - virtual void* mapBufferSubDataCHROMIUM(WGC3Denum target, WGC3Dintptr offset, - WGC3Dsizeiptr size, WGC3Denum access); - virtual void unmapBufferSubDataCHROMIUM(const void*); - virtual void* mapTexSubImage2DCHROMIUM( - WGC3Denum target, - WGC3Dint level, - WGC3Dint xoffset, - WGC3Dint yoffset, - WGC3Dsizei width, - WGC3Dsizei height, - WGC3Denum format, - WGC3Denum type, - WGC3Denum access); - virtual void unmapTexSubImage2DCHROMIUM(const void*); - virtual void copyTextureToParentTextureCHROMIUM( - WebGLId texture, WebGLId parentTexture); - - virtual void getParentToChildLatchCHROMIUM(WGC3Duint* latch_id); - virtual void getChildToParentLatchCHROMIUM(WGC3Duint* latch_id); - virtual void waitLatchCHROMIUM(WGC3Duint latch_id); - virtual void setLatchCHROMIUM(WGC3Duint latch_id); - - virtual WebString getRequestableExtensionsCHROMIUM(); - virtual void requestExtensionCHROMIUM(const char*); - - virtual void blitFramebufferCHROMIUM( - WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, - WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, - WGC3Dbitfield mask, WGC3Denum filter); - virtual void renderbufferStorageMultisampleCHROMIUM( - WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, - WGC3Dsizei width, WGC3Dsizei height); - virtual void activeTexture(WGC3Denum texture); virtual void attachShader(WebGLId program, WebGLId shader); - virtual void bindAttribLocation( - WebGLId program, WGC3Duint index, const WGC3Dchar* name); + virtual void bindAttribLocation(WebGLId program, WGC3Duint index, + const WGC3Dchar* name); virtual void bindBuffer(WGC3Denum target, WebGLId buffer); virtual void bindFramebuffer(WGC3Denum target, WebGLId framebuffer); - virtual void bindRenderbuffer( - WGC3Denum target, WebGLId renderbuffer); + virtual void bindRenderbuffer(WGC3Denum target, WebGLId renderbuffer); virtual void bindTexture(WGC3Denum target, WebGLId texture); - virtual void blendColor( - WGC3Dclampf red, WGC3Dclampf green, WGC3Dclampf blue, WGC3Dclampf alpha); + virtual void blendColor(WGC3Dclampf red, WGC3Dclampf green, + WGC3Dclampf blue, WGC3Dclampf alpha); virtual void blendEquation(WGC3Denum mode); - virtual void blendEquationSeparate(WGC3Denum modeRGB, WGC3Denum modeAlpha); + virtual void blendEquationSeparate(WGC3Denum modeRGB, + WGC3Denum modeAlpha); virtual void blendFunc(WGC3Denum sfactor, WGC3Denum dfactor); - virtual void blendFuncSeparate(WGC3Denum srcRGB, WGC3Denum dstRGB, - WGC3Denum srcAlpha, WGC3Denum dstAlpha); + virtual void blendFuncSeparate(WGC3Denum srcRGB, + WGC3Denum dstRGB, + WGC3Denum srcAlpha, + WGC3Denum dstAlpha); - virtual void bufferData( - WGC3Denum target, WGC3Dsizeiptr size, const void* data, WGC3Denum usage); + virtual void bufferData(WGC3Denum target, WGC3Dsizeiptr size, + const void* data, WGC3Denum usage); virtual void bufferSubData(WGC3Denum target, WGC3Dintptr offset, WGC3Dsizeiptr size, const void* data); virtual WGC3Denum checkFramebufferStatus(WGC3Denum target); virtual void clear(WGC3Dbitfield mask); - virtual void clearColor( - WGC3Dclampf red, WGC3Dclampf green, WGC3Dclampf blue, WGC3Dclampf alpha); + virtual void clearColor(WGC3Dclampf red, WGC3Dclampf green, + WGC3Dclampf blue, WGC3Dclampf alpha); virtual void clearDepth(WGC3Dclampf depth); virtual void clearStencil(WGC3Dint s); virtual void colorMask(WGC3Dboolean red, WGC3Dboolean green, WGC3Dboolean blue, WGC3Dboolean alpha); virtual void compileShader(WebGLId shader); - virtual void copyTexImage2D( - WGC3Denum target, - WGC3Dint level, - WGC3Denum internalformat, - WGC3Dint x, - WGC3Dint y, - WGC3Dsizei width, - WGC3Dsizei height, - WGC3Dint border); - virtual void copyTexSubImage2D( - WGC3Denum target, - WGC3Dint level, - WGC3Dint xoffset, - WGC3Dint yoffset, - WGC3Dint x, - WGC3Dint y, - WGC3Dsizei width, - WGC3Dsizei height); + virtual void copyTexImage2D(WGC3Denum target, + WGC3Dint level, + WGC3Denum internalformat, + WGC3Dint x, + WGC3Dint y, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Dint border); + virtual void copyTexSubImage2D(WGC3Denum target, + WGC3Dint level, + WGC3Dint xoffset, + WGC3Dint yoffset, + WGC3Dint x, + WGC3Dint y, + WGC3Dsizei width, + WGC3Dsizei height); virtual void cullFace(WGC3Denum mode); virtual void depthFunc(WGC3Denum func); virtual void depthMask(WGC3Dboolean flag); @@ -162,42 +130,46 @@ class WebGraphicsContext3DInProcessCommandBufferImpl : public WebGraphicsContext virtual void disable(WGC3Denum cap); virtual void disableVertexAttribArray(WGC3Duint index); virtual void drawArrays(WGC3Denum mode, WGC3Dint first, WGC3Dsizei count); - virtual void drawElements( - WGC3Denum mode, - WGC3Dsizei count, - WGC3Denum type, - WGC3Dintptr offset); + virtual void drawElements(WGC3Denum mode, + WGC3Dsizei count, + WGC3Denum type, + WGC3Dintptr offset); virtual void enable(WGC3Denum cap); virtual void enableVertexAttribArray(WGC3Duint index); virtual void finish(); virtual void flush(); - virtual void framebufferRenderbuffer( - WGC3Denum target, - WGC3Denum attachment, - WGC3Denum renderbuffertarget, - WebGLId renderbuffer); - virtual void framebufferTexture2D( - WGC3Denum target, - WGC3Denum attachment, - WGC3Denum textarget, - WebGLId texture, - WGC3Dint level); + virtual void framebufferRenderbuffer(WGC3Denum target, + WGC3Denum attachment, + WGC3Denum renderbuffertarget, + WebGLId renderbuffer); + virtual void framebufferTexture2D(WGC3Denum target, + WGC3Denum attachment, + WGC3Denum textarget, + WebGLId texture, + WGC3Dint level); virtual void frontFace(WGC3Denum mode); virtual void generateMipmap(WGC3Denum target); - virtual bool getActiveAttrib(WebGLId program, WGC3Duint index, ActiveInfo&); - virtual bool getActiveUniform(WebGLId program, WGC3Duint index, ActiveInfo&); + virtual bool getActiveAttrib(WebGLId program, + WGC3Duint index, + ActiveInfo&); + virtual bool getActiveUniform(WebGLId program, + WGC3Duint index, + ActiveInfo&); - virtual void getAttachedShaders(WebGLId program, WGC3Dsizei maxCount, - WGC3Dsizei* count, WebGLId* shaders); + virtual void getAttachedShaders(WebGLId program, + WGC3Dsizei maxCount, + WGC3Dsizei* count, + WebGLId* shaders); - virtual WGC3Dint getAttribLocation(WebGLId program, const WGC3Dchar* name); + virtual WGC3Dint getAttribLocation(WebGLId program, const WGC3Dchar* name); virtual void getBooleanv(WGC3Denum pname, WGC3Dboolean* value); - virtual void getBufferParameteriv( - WGC3Denum target, WGC3Denum pname, WGC3Dint* value); + virtual void getBufferParameteriv(WGC3Denum target, + WGC3Denum pname, + WGC3Dint* value); virtual Attributes getContextAttributes(); @@ -207,54 +179,56 @@ class WebGraphicsContext3DInProcessCommandBufferImpl : public WebGraphicsContext virtual void getFloatv(WGC3Denum pname, WGC3Dfloat* value); - virtual void getFramebufferAttachmentParameteriv( - WGC3Denum target, - WGC3Denum attachment, - WGC3Denum pname, - WGC3Dint* value); + virtual void getFramebufferAttachmentParameteriv(WGC3Denum target, + WGC3Denum attachment, + WGC3Denum pname, + WGC3Dint* value); virtual void getIntegerv(WGC3Denum pname, WGC3Dint* value); - virtual void getProgramiv( - WebGLId program, WGC3Denum pname, WGC3Dint* value); + virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value); - virtual WebString getProgramInfoLog(WebGLId program); + virtual WebKit::WebString getProgramInfoLog(WebGLId program); - virtual void getRenderbufferParameteriv( - WGC3Denum target, WGC3Denum pname, WGC3Dint* value); + virtual void getRenderbufferParameteriv(WGC3Denum target, + WGC3Denum pname, + WGC3Dint* value); - virtual void getShaderiv( - WebGLId shader, WGC3Denum pname, WGC3Dint* value); + virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value); - virtual WebString getShaderInfoLog(WebGLId shader); + virtual WebKit::WebString getShaderInfoLog(WebGLId shader); // TBD - // void glGetShaderPrecisionFormat( - // GLenum shadertype, GLenum precisiontype, - // GLint* range, GLint* precision); - - virtual WebString getShaderSource(WebGLId shader); - virtual WebString getString(WGC3Denum name); - - virtual void getTexParameterfv( - WGC3Denum target, WGC3Denum pname, WGC3Dfloat* value); - virtual void getTexParameteriv( - WGC3Denum target, WGC3Denum pname, WGC3Dint* value); - - virtual void getUniformfv( - WebGLId program, WGC3Dint location, WGC3Dfloat* value); - virtual void getUniformiv( - WebGLId program, WGC3Dint location, WGC3Dint* value); + // void glGetShaderPrecisionFormat (GLenum shadertype, + // GLenum precisiontype, + // GLint* range, + // GLint* precision); + + virtual WebKit::WebString getShaderSource(WebGLId shader); + virtual WebKit::WebString getString(WGC3Denum name); + + virtual void getTexParameterfv(WGC3Denum target, + WGC3Denum pname, + WGC3Dfloat* value); + virtual void getTexParameteriv(WGC3Denum target, + WGC3Denum pname, + WGC3Dint* value); + + virtual void getUniformfv(WebGLId program, + WGC3Dint location, + WGC3Dfloat* value); + virtual void getUniformiv(WebGLId program, + WGC3Dint location, + WGC3Dint* value); virtual WGC3Dint getUniformLocation(WebGLId program, const WGC3Dchar* name); - virtual void getVertexAttribfv( - WGC3Duint index, WGC3Denum pname, WGC3Dfloat* value); - virtual void getVertexAttribiv( - WGC3Duint index, WGC3Denum pname, WGC3Dint* value); + virtual void getVertexAttribfv(WGC3Duint index, WGC3Denum pname, + WGC3Dfloat* value); + virtual void getVertexAttribiv(WGC3Duint index, WGC3Denum pname, + WGC3Dint* value); - virtual WGC3Dsizeiptr getVertexAttribOffset( - WGC3Duint index, WGC3Denum pname); + virtual WGC3Dsizeiptr getVertexAttribOffset(WGC3Duint index, WGC3Denum pname); virtual void hint(WGC3Denum target, WGC3Denum mode); virtual WGC3Dboolean isBuffer(WebGLId buffer); @@ -264,103 +238,111 @@ class WebGraphicsContext3DInProcessCommandBufferImpl : public WebGraphicsContext virtual WGC3Dboolean isRenderbuffer(WebGLId renderbuffer); virtual WGC3Dboolean isShader(WebGLId shader); virtual WGC3Dboolean isTexture(WebGLId texture); - virtual void lineWidth(WGC3Dfloat width); + virtual void lineWidth(WGC3Dfloat); virtual void linkProgram(WebGLId program); virtual void pixelStorei(WGC3Denum pname, WGC3Dint param); virtual void polygonOffset(WGC3Dfloat factor, WGC3Dfloat units); - virtual void readPixels( - WGC3Dint x, WGC3Dint y, - WGC3Dsizei width, WGC3Dsizei height, - WGC3Denum format, - WGC3Denum type, - void* pixels); + virtual void readPixels(WGC3Dint x, + WGC3Dint y, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Denum format, + WGC3Denum type, + void* pixels); virtual void releaseShaderCompiler(); - virtual void renderbufferStorage( - WGC3Denum target, - WGC3Denum internalformat, - WGC3Dsizei width, - WGC3Dsizei height); - virtual void sampleCoverage(WGC3Dclampf value, WGC3Dboolean invert); - virtual void scissor( - WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height); - virtual void shaderSource(WebGLId shader, const WGC3Dchar* source); + virtual void renderbufferStorage(WGC3Denum target, + WGC3Denum internalformat, + WGC3Dsizei width, + WGC3Dsizei height); + virtual void sampleCoverage(WGC3Dfloat value, WGC3Dboolean invert); + virtual void scissor(WGC3Dint x, WGC3Dint y, + WGC3Dsizei width, WGC3Dsizei height); + virtual void shaderSource(WebGLId shader, const WGC3Dchar* string); virtual void stencilFunc(WGC3Denum func, WGC3Dint ref, WGC3Duint mask); - virtual void stencilFuncSeparate( - WGC3Denum face, WGC3Denum func, WGC3Dint ref, WGC3Duint mask); + virtual void stencilFuncSeparate(WGC3Denum face, + WGC3Denum func, + WGC3Dint ref, + WGC3Duint mask); virtual void stencilMask(WGC3Duint mask); virtual void stencilMaskSeparate(WGC3Denum face, WGC3Duint mask); - virtual void stencilOp(WGC3Denum fail, WGC3Denum zfail, WGC3Denum zpass); - virtual void stencilOpSeparate( - WGC3Denum face, - WGC3Denum fail, - WGC3Denum zfail, - WGC3Denum zpass); - - virtual void texImage2D( - WGC3Denum target, - WGC3Dint level, - WGC3Denum internalformat, - WGC3Dsizei width, - WGC3Dsizei height, - WGC3Dint border, - WGC3Denum format, - WGC3Denum type, - const void* pixels); - - virtual void texParameterf( - WGC3Denum target, WGC3Denum pname, WGC3Dfloat param); - virtual void texParameteri( - WGC3Denum target, WGC3Denum pname, WGC3Dint param); - - virtual void texSubImage2D( - WGC3Denum target, - WGC3Dint level, - WGC3Dint xoffset, - WGC3Dint yoffset, - WGC3Dsizei width, - WGC3Dsizei height, - WGC3Denum format, - WGC3Denum type, - const void* pixels); + virtual void stencilOp(WGC3Denum fail, + WGC3Denum zfail, + WGC3Denum zpass); + virtual void stencilOpSeparate(WGC3Denum face, + WGC3Denum fail, + WGC3Denum zfail, + WGC3Denum zpass); + + virtual void texImage2D(WGC3Denum target, + WGC3Dint level, + WGC3Denum internalformat, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Dint border, + WGC3Denum format, + WGC3Denum type, + const void* pixels); + + virtual void texParameterf(WGC3Denum target, + WGC3Denum pname, + WGC3Dfloat param); + virtual void texParameteri(WGC3Denum target, + WGC3Denum pname, + WGC3Dint param); + + virtual void texSubImage2D(WGC3Denum target, + WGC3Dint level, + WGC3Dint xoffset, + WGC3Dint yoffset, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Denum format, + WGC3Denum type, + const void* pixels); virtual void uniform1f(WGC3Dint location, WGC3Dfloat x); - virtual void uniform1fv(WGC3Dint location, WGC3Dsizei count, - const WGC3Dfloat* v); + virtual void uniform1fv(WGC3Dint location, + WGC3Dsizei count, const WGC3Dfloat* v); virtual void uniform1i(WGC3Dint location, WGC3Dint x); - virtual void uniform1iv(WGC3Dint location, WGC3Dsizei count, - const WGC3Dint* v); + virtual void uniform1iv(WGC3Dint location, + WGC3Dsizei count, const WGC3Dint* v); virtual void uniform2f(WGC3Dint location, WGC3Dfloat x, WGC3Dfloat y); - virtual void uniform2fv(WGC3Dint location, WGC3Dsizei count, - const WGC3Dfloat* v); + virtual void uniform2fv(WGC3Dint location, + WGC3Dsizei count, const WGC3Dfloat* v); virtual void uniform2i(WGC3Dint location, WGC3Dint x, WGC3Dint y); - virtual void uniform2iv(WGC3Dint location, WGC3Dsizei count, - const WGC3Dint* v); + virtual void uniform2iv(WGC3Dint location, + WGC3Dsizei count, const WGC3Dint* v); virtual void uniform3f(WGC3Dint location, WGC3Dfloat x, WGC3Dfloat y, WGC3Dfloat z); - virtual void uniform3fv(WGC3Dint location, WGC3Dsizei count, - const WGC3Dfloat* v); - virtual void uniform3i(WGC3Dint location, WGC3Dint x, WGC3Dint y, WGC3Dint z); - virtual void uniform3iv(WGC3Dint location, WGC3Dsizei count, - const WGC3Dint* v); - virtual void uniform4f(WGC3Dint location, WGC3Dfloat x, WGC3Dfloat y, + virtual void uniform3fv(WGC3Dint location, + WGC3Dsizei count, const WGC3Dfloat* v); + virtual void uniform3i(WGC3Dint location, + WGC3Dint x, WGC3Dint y, WGC3Dint z); + virtual void uniform3iv(WGC3Dint location, + WGC3Dsizei count, const WGC3Dint* v); + virtual void uniform4f(WGC3Dint location, + WGC3Dfloat x, WGC3Dfloat y, WGC3Dfloat z, WGC3Dfloat w); - virtual void uniform4fv(WGC3Dint location, WGC3Dsizei count, - const WGC3Dfloat* v); - virtual void uniform4i(WGC3Dint location, WGC3Dint x, WGC3Dint y, - WGC3Dint z, WGC3Dint w); - virtual void uniform4iv(WGC3Dint location, WGC3Dsizei count, - const WGC3Dint* v); - virtual void uniformMatrix2fv( - WGC3Dint location, WGC3Dsizei count, - WGC3Dboolean transpose, const WGC3Dfloat* value); - virtual void uniformMatrix3fv( - WGC3Dint location, WGC3Dsizei count, - WGC3Dboolean transpose, const WGC3Dfloat* value); - virtual void uniformMatrix4fv( - WGC3Dint location, WGC3Dsizei count, - WGC3Dboolean transpose, const WGC3Dfloat* value); + virtual void uniform4fv(WGC3Dint location, + WGC3Dsizei count, const WGC3Dfloat* v); + virtual void uniform4i(WGC3Dint location, + WGC3Dint x, WGC3Dint y, WGC3Dint z, WGC3Dint w); + virtual void uniform4iv(WGC3Dint location, + WGC3Dsizei count, const WGC3Dint* v); + virtual void uniformMatrix2fv(WGC3Dint location, + WGC3Dsizei count, + WGC3Dboolean transpose, + const WGC3Dfloat* value); + virtual void uniformMatrix3fv(WGC3Dint location, + WGC3Dsizei count, + WGC3Dboolean transpose, + const WGC3Dfloat* value); + virtual void uniformMatrix4fv(WGC3Dint location, + WGC3Dsizei count, + WGC3Dboolean transpose, + const WGC3Dfloat* value); virtual void useProgram(WebGLId program); virtual void validateProgram(WebGLId program); @@ -369,22 +351,22 @@ class WebGraphicsContext3DInProcessCommandBufferImpl : public WebGraphicsContext virtual void vertexAttrib1fv(WGC3Duint index, const WGC3Dfloat* values); virtual void vertexAttrib2f(WGC3Duint index, WGC3Dfloat x, WGC3Dfloat y); virtual void vertexAttrib2fv(WGC3Duint index, const WGC3Dfloat* values); - virtual void vertexAttrib3f( - WGC3Duint index, WGC3Dfloat x, WGC3Dfloat y, WGC3Dfloat z); + virtual void vertexAttrib3f(WGC3Duint index, + WGC3Dfloat x, WGC3Dfloat y, WGC3Dfloat z); virtual void vertexAttrib3fv(WGC3Duint index, const WGC3Dfloat* values); - virtual void vertexAttrib4f( - WGC3Duint index, WGC3Dfloat x, WGC3Dfloat y, WGC3Dfloat z, WGC3Dfloat w); + virtual void vertexAttrib4f(WGC3Duint index, + WGC3Dfloat x, WGC3Dfloat y, + WGC3Dfloat z, WGC3Dfloat w); virtual void vertexAttrib4fv(WGC3Duint index, const WGC3Dfloat* values); - virtual void vertexAttribPointer( - WGC3Duint index, - WGC3Dint size, - WGC3Denum type, - WGC3Dboolean normalized, - WGC3Dsizei stride, - WGC3Dintptr offset); + virtual void vertexAttribPointer(WGC3Duint index, + WGC3Dint size, + WGC3Denum type, + WGC3Dboolean normalized, + WGC3Dsizei stride, + WGC3Dintptr offset); - virtual void viewport( - WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height); + virtual void viewport(WGC3Dint x, WGC3Dint y, + WGC3Dsizei width, WGC3Dsizei height); // Support for buffer creation and deletion virtual WebGLId createBuffer(); @@ -401,80 +383,96 @@ class WebGraphicsContext3DInProcessCommandBufferImpl : public WebGraphicsContext virtual void deleteShader(WebGLId); virtual void deleteTexture(WebGLId); - virtual void setContextLostCallback( - WebGraphicsContext3D::WebGraphicsContextLostCallback* callback) {} + virtual void synthesizeGLError(WGC3Denum); - private: - // ANGLE related. - struct ShaderSourceEntry; + virtual void* mapBufferSubDataCHROMIUM( + WGC3Denum target, WGC3Dintptr offset, + WGC3Dsizeiptr size, WGC3Denum access); + virtual void unmapBufferSubDataCHROMIUM(const void*); + virtual void* mapTexSubImage2DCHROMIUM( + WGC3Denum target, + WGC3Dint level, + WGC3Dint xoffset, + WGC3Dint yoffset, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Denum format, + WGC3Denum type, + WGC3Denum access); + virtual void unmapTexSubImage2DCHROMIUM(const void*); - typedef base::hash_map<WebGLId, ShaderSourceEntry*> ShaderSourceMap; + virtual void copyTextureToParentTextureCHROMIUM( + WebGLId texture, WebGLId parentTexture); -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - void FlipVertically(unsigned char* framebuffer, - unsigned int width, - unsigned int height); -#endif + virtual void getParentToChildLatchCHROMIUM(WGC3Duint* latch_id); + virtual void getChildToParentLatchCHROMIUM(WGC3Duint* latch_id); + virtual void waitLatchCHROMIUM(WGC3Duint latch_id); + virtual void setLatchCHROMIUM(WGC3Duint latch_id); - // Take into account the user's requested context creation attributes, in - // particular stencil and antialias, and determine which could or could - // not be honored based on the capabilities of the OpenGL implementation. - void ValidateAttributes(); - - // Resolve the given rectangle of the multisampled framebuffer if necessary. - void ResolveMultisampledFramebuffer( - WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height); - - bool AngleCreateCompilers(); - void AngleDestroyCompilers(); - bool AngleValidateShaderSource(ShaderSourceEntry* entry); - - WebGraphicsContext3D::Attributes attributes_; - bool initialized_; - bool render_directly_to_web_view_; - bool is_gles2_; - bool have_ext_framebuffer_object_; - bool have_ext_framebuffer_multisample_; - bool have_angle_framebuffer_multisample_; - - WebGLId texture_; - WebGLId fbo_; - WebGLId depth_stencil_buffer_; - int cached_width_, cached_height_; + virtual void rateLimitOffscreenContextCHROMIUM(); - // For multisampling - WebGLId multisample_fbo_; - WebGLId multisample_depth_stencil_buffer_; - WebGLId multisample_color_buffer_; + virtual WebKit::WebString getRequestableExtensionsCHROMIUM(); + virtual void requestExtensionCHROMIUM(const char*); - // For tracking which FBO is bound - WebGLId bound_fbo_; + virtual void blitFramebufferCHROMIUM( + WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, + WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, + WGC3Dbitfield mask, WGC3Denum filter); + virtual void renderbufferStorageMultisampleCHROMIUM( + WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, + WGC3Dsizei width, WGC3Dsizei height); - // For tracking which texture is bound - WebGLId bound_texture_; + virtual WebGLId createCompositorTexture(WGC3Dsizei width, WGC3Dsizei height); + virtual void deleteCompositorTexture(WebGLId parent_texture); + virtual void copyTextureToCompositor(WebGLId texture, + WebGLId parent_texture); - // FBO used for copying child texture to parent texture. - WebGLId copy_texture_to_parent_texture_fbo_; + virtual void setContextLostCallback( + WebGraphicsContext3D::WebGraphicsContextLostCallback* callback); -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - unsigned char* scanline_; + private: + // SwapBuffers callback. + void OnSwapBuffersComplete(); + virtual void OnContextLost(); + + // Used to try to find bugs in code that calls gl directly through the gl api + // instead of going through WebGraphicsContext3D. + void ClearContext(); + + // The context we use for OpenGL rendering. + GLInProcessContext* context_; + // The GLES2Implementation we use for OpenGL rendering. + ::gpu::gles2::GLES2Implementation* gl_; + + // If rendering directly to WebView, weak pointer to it. + WebKit::WebView* web_view_; +#if defined(OS_MACOSX) + // "Fake" plugin window handle in browser process for the compositor's output. + gfx::PluginWindowHandle plugin_handle_; #endif + WebGraphicsContext3D::WebGraphicsContextLostCallback* context_lost_callback_; - // Errors raised by synthesizeGLError(). - std::list<WGC3Denum> synthetic_errors_list_; - std::set<WGC3Denum> synthetic_errors_set_; + WebKit::WebGraphicsContext3D::Attributes attributes_; + int cached_width_, cached_height_; - scoped_refptr<gfx::GLContext> gl_context_; - scoped_refptr<gfx::GLSurface> gl_surface_; + // For tracking which FBO is bound. + WebGLId bound_fbo_; - ShaderSourceMap shader_source_map_; + // Errors raised by synthesizeGLError(). + std::vector<WGC3Denum> synthetic_errors_; - ShHandle fragment_compiler_; - ShHandle vertex_compiler_; +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + scoped_array<uint8> scanline_; + void FlipVertically(uint8* framebuffer, + unsigned int width, + unsigned int height); +#endif }; } // namespace gpu } // namespace webkit +#endif // defined(ENABLE_GPU) #endif // WEBKIT_GPU_WEBGRAPHICSCONTEXT3D_IN_PROCESS_COMMAND_BUFFER_IMPL_H_ + diff --git a/webkit/gpu/webkit_gpu.gypi b/webkit/gpu/webkit_gpu.gypi index e15f28a..563cdda 100644 --- a/webkit/gpu/webkit_gpu.gypi +++ b/webkit/gpu/webkit_gpu.gypi @@ -1,4 +1,4 @@ -# Copyright (c) 2010 The Chromium Authors. All rights reserved. +# Copyright (c) 2011 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. @@ -9,10 +9,16 @@ 'type': 'static_library', 'dependencies': [ '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/gpu/gpu.gyp:command_buffer_service', + '<(DEPTH)/gpu/gpu.gyp:command_buffer_client', + '<(DEPTH)/gpu/gpu.gyp:gles2_c_lib', '<(DEPTH)/third_party/angle/src/build_angle.gyp:translator_common', '<(DEPTH)/third_party/angle/src/build_angle.gyp:translator_glsl', '<(DEPTH)/ui/gfx/gl/gl.gyp:gl', ], + 'include_dirs': [ + '<(DEPTH)/skia/config', + ], 'sources': [ # This list contains all .h and .cc in gpu except for test code. 'webgraphicscontext3d_in_process_command_buffer_impl.cc', |