diff options
-rw-r--r-- | webkit/DEPS | 4 | ||||
-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 | ||||
-rw-r--r-- | webkit/plugins/ppapi/plugin_delegate.h | 2 | ||||
-rw-r--r-- | webkit/support/webkit_support.cc | 3 | ||||
-rw-r--r-- | webkit/tools/layout_tests/test_expectations.txt | 22 |
7 files changed, 1543 insertions, 1407 deletions
diff --git a/webkit/DEPS b/webkit/DEPS index b8011c6..b1db55e 100644 --- a/webkit/DEPS +++ b/webkit/DEPS @@ -18,6 +18,10 @@ include_rules = [ # For gpu/ "+app/gfx", + "+gpu/command_buffer/client", + "+gpu/command_buffer/common", + "+gpu/command_buffer/service", + "+gpu/GLES2", # TODO(brettw) - review these; move up if it's ok, or remove the dependency "+crypto", 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', diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h index 41b6e6b..931a39d 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -172,7 +172,7 @@ class PluginDelegate { // This call will return the address of the command buffer for this context // that is constructed in Initialize() and is valid until this context is // destroyed. - virtual gpu::CommandBuffer* GetCommandBuffer() = 0; + virtual ::gpu::CommandBuffer* GetCommandBuffer() = 0; // Set an optional callback that will be invoked when the context is lost // (e.g. gpu process crash). Takes ownership of the callback. diff --git a/webkit/support/webkit_support.cc b/webkit/support/webkit_support.cc index 6b40477..ce32835 100644 --- a/webkit/support/webkit_support.cc +++ b/webkit/support/webkit_support.cc @@ -214,7 +214,8 @@ class TaskAdaptorHolder : public CancelableTask { }; webkit_support::GraphicsContext3DImplementation - g_graphics_context_3d_implementation = webkit_support::IN_PROCESS; + g_graphics_context_3d_implementation = + webkit_support::IN_PROCESS_COMMAND_BUFFER; } // namespace diff --git a/webkit/tools/layout_tests/test_expectations.txt b/webkit/tools/layout_tests/test_expectations.txt index 707c890..da186ed 100644 --- a/webkit/tools/layout_tests/test_expectations.txt +++ b/webkit/tools/layout_tests/test_expectations.txt @@ -6,3 +6,25 @@ // until the changes can be landed upstream. // PLEASE DO NOT LEAVE ENTRIES IN THIS FILE FOR MORE THAN 24 HRS. +// The need for rebaselines is conflicting with the TIMEOUT expectation upstream + +// Issues introduced with bug 84157 +BUGGMAN : plugins/embed-attributes-style.html = IMAGE+TEXT +BUGGMAN : svg/as-image/svg-as-background-with-relative-size.html = IMAGE+TEXT +BUGGMAN : svg/custom/embedding-external-svgs.xhtml = IMAGE+TEXT +BUGGMAN : svg/dynamic-updates/SVGFEDropShadowElement-dom-shadow-color-attr.html = IMAGE +BUGGMAN : svg/dynamic-updates/SVGFEDropShadowElement-dom-shadow-opacity-attr.html = IMAGE +BUGGMAN : svg/dynamic-updates/SVGFEDropShadowElement-svgdom-shadow-color-prop.html = IMAGE +BUGGMAN : svg/dynamic-updates/SVGFEDropShadowElement-svgdom-shadow-opacity-prop.html = IMAGE +BUGGMAN : fast/dom/object-plugin-hides-properties.html = TEXT +BUGGMAN : fast/js/property-getters-and-setters.html = TEXT +BUGGMAN : fast/canvas/canvas-as-image-incremental-repaint.html = IMAGE +BUGGMAN : fast/canvas/canvas-as-image.html = IMAGE +BUGGMAN : fast/canvas/canvas-bg-zoom.html = IMAGE +BUGGMAN : fast/canvas/canvas-bg.html = IMAGE +BUGGMAN : fast/canvas/canvas-currentColor.html = TEXT +BUGGMAN : fast/canvas/canvas-fillPath-shadow.html = TEXT +BUGGMAN : fast/canvas/canvas-transform-skewed.html = IMAGE +BUGGMAN : fast/canvas/zero-size-fill-rect.html = IMAGE +BUGGMAN : media/video-canvas-alpha.html = IMAGE + |