diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-06 00:00:07 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-06 00:00:07 +0000 |
commit | 5aa6a312dc935c3392e025e97daded48f5363a05 (patch) | |
tree | 2c1a286841459eba6b8b38528e2a18057f03c9d4 /chrome | |
parent | 7bc4b5d06145e8753fdc8b2db04a5fb20ab86299 (diff) | |
download | chromium_src-5aa6a312dc935c3392e025e97daded48f5363a05.zip chromium_src-5aa6a312dc935c3392e025e97daded48f5363a05.tar.gz chromium_src-5aa6a312dc935c3392e025e97daded48f5363a05.tar.bz2 |
Reland r65152 with mac and linux fix.
Original review URL: http://codereview.chromium.org/3531008
TEST=try, ui_tests
BUG=none
Review URL: http://codereview.chromium.org/4545003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65283 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/renderer/ggl/ggl.cc | 50 | ||||
-rw-r--r-- | chrome/renderer/ggl/ggl.h | 18 | ||||
-rw-r--r-- | chrome/renderer/pepper_plugin_delegate_impl.cc | 276 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 16 | ||||
-rw-r--r-- | chrome/renderer/webgraphicscontext3d_command_buffer_impl.h | 2 |
5 files changed, 139 insertions, 223 deletions
diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc index 0589852..cfe6743 100644 --- a/chrome/renderer/ggl/ggl.cc +++ b/chrome/renderer/ggl/ggl.cc @@ -6,7 +6,6 @@ #include "base/ref_counted.h" #include "base/singleton.h" -#include "base/thread_local.h" #include "base/weak_ptr.h" #include "chrome/renderer/command_buffer_proxy.h" #include "chrome/renderer/ggl/ggl.h" @@ -35,8 +34,6 @@ const int32 kCommandBufferSize = 1024 * 1024; // creation attributes. const int32 kTransferBufferSize = 1024 * 1024; -base::ThreadLocalPointer<Context> g_current_context; - // Singleton used to initialize and terminate the gles2 library. class GLES2Initializer { public: @@ -77,7 +74,7 @@ class Context : public base::SupportsWeakPtr<Context> { // Provides a callback that will be invoked when SwapBuffers has completed // service side. - void SetSwapBuffersCallback(Callback1<Context*>::Type* callback) { + void SetSwapBuffersCallback(Callback0::Type* callback) { swap_buffers_callback_.reset(callback); } @@ -117,17 +114,22 @@ class Context : public base::SupportsWeakPtr<Context> { // TODO(gman): Remove this. void DisableShaderTranslation(); + gpu::gles2::GLES2Implementation* gles2_implementation() const { + return gles2_implementation_; + } private: void OnSwapBuffers(); scoped_refptr<GpuChannelHost> channel_; base::WeakPtr<Context> parent_; - scoped_ptr<Callback1<Context*>::Type> swap_buffers_callback_; + scoped_ptr<Callback0::Type> swap_buffers_callback_; uint32 parent_texture_id_; CommandBufferProxy* command_buffer_; gpu::gles2::GLES2CmdHelper* gles2_helper_; int32 transfer_buffer_id_; gpu::gles2::GLES2Implementation* gles2_implementation_; + gfx::Size size_; + Error last_error_; DISALLOW_COPY_AND_ASSIGN(Context); @@ -262,19 +264,25 @@ bool Context::Initialize(gfx::NativeViewId view, transfer_buffer_id_, false); + size_ = size; + return true; } #if defined(OS_MACOSX) void Context::ResizeOnscreen(const gfx::Size& size) { DCHECK(size.width() > 0 && size.height() > 0); + size_ = size; command_buffer_->SetWindowSize(size); } #endif void Context::ResizeOffscreen(const gfx::Size& size) { DCHECK(size.width() > 0 && size.height() > 0); - command_buffer_->ResizeOffscreenFrameBuffer(size); + if (size_ != size) { + command_buffer_->ResizeOffscreenFrameBuffer(size); + size_ = size; + } } uint32 Context::CreateParentTexture(const gfx::Size& size) const { @@ -343,7 +351,6 @@ void Context::Destroy() { } bool Context::MakeCurrent(Context* context) { - g_current_context.Set(context); if (context) { gles2::SetGLContext(context->gles2_implementation_); @@ -405,7 +412,7 @@ void Context::DisableShaderTranslation() { void Context::OnSwapBuffers() { if (swap_buffers_callback_.get()) - swap_buffers_callback_->Run(this); + swap_buffers_callback_->Run(); } #endif // ENABLE_GPU @@ -480,7 +487,7 @@ void DeleteParentTexture(Context* context, uint32 texture) { } void SetSwapBuffersCallback(Context* context, - Callback1<Context*>::Type* callback) { + Callback0::Type* callback) { #if defined(ENABLE_GPU) context->SetSwapBuffersCallback(callback); #endif @@ -494,14 +501,6 @@ bool MakeCurrent(Context* context) { #endif } -Context* GetCurrentContext() { -#if defined(ENABLE_GPU) - return g_current_context.Get(); -#else - return NULL; -#endif -} - bool SwapBuffers(Context* context) { #if defined(ENABLE_GPU) if (!context) @@ -518,9 +517,6 @@ bool DestroyContext(Context* context) { if (!context) return false; - if (context == GetCurrentContext()) - MakeCurrent(NULL); - delete context; return true; #else @@ -537,12 +533,8 @@ media::VideoDecodeContext* CreateVideoDecodeContext( return context->CreateVideoDecodeContext(message_loop, hardware_decoder); } -Error GetError() { +Error GetError(Context* context) { #if defined(ENABLE_GPU) - Context* context = GetCurrentContext(); - if (!context) - return BAD_CONTEXT; - return context->GetError(); #else return NOT_INITIALIZED; @@ -557,4 +549,12 @@ void DisableShaderTranslation(Context* context) { } #endif } + +gpu::gles2::GLES2Implementation* GetImplementation(Context* context) { + if (!context) + return NULL; + + return context->gles2_implementation(); +} + } // namespace ggl diff --git a/chrome/renderer/ggl/ggl.h b/chrome/renderer/ggl/ggl.h index 1d53f57..54a7f8e 100644 --- a/chrome/renderer/ggl/ggl.h +++ b/chrome/renderer/ggl/ggl.h @@ -18,6 +18,12 @@ class GpuChannelHost; class MessageLoop; +namespace gpu { +namespace gles2 { +class GLES2Implementation; +} +} + namespace media { class VideoDecodeContext; class VideoDecodeEngine; @@ -120,15 +126,11 @@ void DeleteParentTexture(Context* context, uint32 texture); // Provides a callback that will be invoked when SwapBuffers has completed // service side. -void SetSwapBuffersCallback(Context* context, - Callback1<Context*>::Type* callback); +void SetSwapBuffersCallback(Context* context, Callback0::Type* callback); // Set the current GGL context for the calling thread. bool MakeCurrent(Context* context); -// Get the calling thread's current GGL context. -Context* GetCurrentContext(); - // For a view context, display everything that has been rendered since the // last call. For an offscreen context, resolve everything that has been // rendered since the last call to a copy that can be accessed by the parent @@ -153,8 +155,12 @@ media::VideoDecodeContext* CreateVideoDecodeContext(Context* context, // TODO(gman): Remove this void DisableShaderTranslation(Context* context); +// Allows direct access to the GLES2 implementation so a context +// can be used without making it current. +gpu::gles2::GLES2Implementation* GetImplementation(Context* context); + // Return the current GGL error. -Error GetError(); +Error GetError(Context* context); } // namespace ggl diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc index 06ca49a..d7b6c87 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.cc +++ b/chrome/renderer/pepper_plugin_delegate_impl.cc @@ -8,6 +8,7 @@ #include "app/l10n_util.h" #include "app/surface/transport_dib.h" +#include "base/callback.h" #include "base/file_path.h" #include "base/logging.h" #include "base/scoped_ptr.h" @@ -21,9 +22,13 @@ #include "chrome/common/render_messages_params.h" #include "chrome/renderer/audio_message_filter.h" #include "chrome/renderer/command_buffer_proxy.h" +#include "chrome/renderer/ggl/ggl.h" +#include "chrome/renderer/gpu_channel_host.h" #include "chrome/renderer/render_thread.h" #include "chrome/renderer/render_view.h" +#include "chrome/renderer/webgraphicscontext3d_command_buffer_impl.h" #include "chrome/renderer/webplugin_delegate_proxy.h" +#include "gfx/size.h" #include "grit/locale_settings.h" #include "ppapi/c/dev/pp_video_dev.h" #include "third_party/WebKit/WebKit/chromium/public/WebFileChooserCompletion.h" @@ -80,139 +85,29 @@ class PlatformImage2DImpl : public pepper::PluginDelegate::PlatformImage2D { class PlatformContext3DImpl : public pepper::PluginDelegate::PlatformContext3D { public: - explicit PlatformContext3DImpl(RenderView* render_view) - : render_view_(render_view), - nested_delegate_(NULL), - command_buffer_(NULL), - renderview_to_webplugin_adapter_(render_view) {} + explicit PlatformContext3DImpl(WebKit::WebView* web_view) + : web_view_(web_view), + context_(NULL) { + } virtual ~PlatformContext3DImpl() { - if (nested_delegate_) { - nested_delegate_->DestroyCommandBuffer(command_buffer_); - nested_delegate_->PluginDestroyed(); + if (context_) { + ggl::DestroyContext(context_); + context_ = NULL; } } - virtual bool Init(const gfx::Rect& position, const gfx::Rect& clip); - - virtual gpu::CommandBuffer* GetCommandBuffer() { - return command_buffer_; - } - - virtual void SetNotifyRepaintTask(Task* task) { - command_buffer_->SetNotifyRepaintTask(task); - } + virtual bool Init(); + virtual bool SwapBuffers(); + virtual unsigned GetError(); + virtual void SetSwapBuffersCallback(Callback0::Type* callback); + void ResizeBackingTexture(const gfx::Size& size); + virtual unsigned GetBackingTextureId(); + virtual gpu::gles2::GLES2Implementation* GetGLES2Implementation(); private: - - class WebPluginAdapter : public webkit_glue::WebPlugin { - public: - explicit WebPluginAdapter(RenderView* render_view) - : render_view_(render_view) {} - - virtual void SetWindow(gfx::PluginWindowHandle window) { - render_view_->CreatedPluginWindow(window); - } - - virtual void WillDestroyWindow(gfx::PluginWindowHandle window) { - render_view_->WillDestroyPluginWindow(window); - } - - virtual void SetAcceptsInputEvents(bool accepts) { - NOTREACHED(); - } - -#if defined(OS_WIN) - virtual void SetWindowlessPumpEvent(HANDLE pump_messages_event) { - NOTREACHED(); - } -#endif - - virtual void CancelResource(unsigned long id) { - NOTREACHED(); - } - - virtual void Invalidate() { - NOTREACHED(); - } - - virtual void InvalidateRect(const gfx::Rect& rect) { - NOTREACHED(); - } - - virtual NPObject* GetWindowScriptNPObject() { - NOTREACHED(); - return NULL; - } - - virtual NPObject* GetPluginElement() { - NOTREACHED(); - return NULL; - } - - virtual void SetCookie(const GURL& url, - const GURL& first_party_for_cookies, - const std::string& cookie) { - NOTREACHED(); - } - - virtual std::string GetCookies(const GURL& url, - const GURL& first_party_for_cookies) { - NOTREACHED(); - return std::string(); - } - - virtual void ShowModalHTMLDialog(const GURL& url, int width, int height, - const std::string& json_arguments, - std::string* json_retval) { - NOTREACHED(); - } - - virtual void OnMissingPluginStatus(int status) { - NOTREACHED(); - } - - virtual void HandleURLRequest(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - int notify_id, - bool popups_allowed) { - NOTREACHED(); - } - - virtual void CancelDocumentLoad() { - NOTREACHED(); - } - - virtual void InitiateHTTPRangeRequest(const char* url, - const char* range_info, - int range_request_id) { - NOTREACHED(); - } - - virtual bool IsOffTheRecord() { - NOTREACHED(); - return false; - } - - virtual void SetDeferResourceLoading(unsigned long resource_id, - bool defer) { - NOTREACHED(); - } - - private: - RenderView* render_view_; - }; - - void SendNestedDelegateGeometryToBrowser(const gfx::Rect& window_rect, - const gfx::Rect& clip_rect); - - RenderView* render_view_; - WebPluginDelegateProxy* nested_delegate_; - CommandBufferProxy* command_buffer_; - WebPluginAdapter renderview_to_webplugin_adapter_; + WebKit::WebView* web_view_; + ggl::Context* context_; }; #endif // ENABLE_GPU @@ -278,76 +173,83 @@ class PlatformAudioImpl #ifdef ENABLE_GPU -bool PlatformContext3DImpl::Init(const gfx::Rect& position, - const gfx::Rect& clip) { -#if defined(ENABLE_GPU) +bool PlatformContext3DImpl::Init() { // Ignore initializing more than once. - if (nested_delegate_) + if (context_) return true; - // Create an instance of the GPU plugin that is responsible for 3D - // rendering. - nested_delegate_ = new WebPluginDelegateProxy( - std::string("application/vnd.google.chrome.gpu-plugin"), - render_view_->AsWeakPtr()); - - if (nested_delegate_->Initialize(GURL(), std::vector<std::string>(), - std::vector<std::string>(), - &renderview_to_webplugin_adapter_, - false)) { - // Ensure the window has the correct size before initializing the - // command buffer. - nested_delegate_->UpdateGeometry(position, clip); - - // Ask the GPU plugin to create a command buffer and return a proxy. - command_buffer_ = nested_delegate_->CreateCommandBuffer(); - if (command_buffer_) { - // Initialize the proxy command buffer. - if (command_buffer_->Initialize(kDefaultCommandBufferSize)) { -#if defined(OS_MACOSX) - command_buffer_->SetWindowSize(position.size()); -#endif // OS_MACOSX + WebGraphicsContext3DCommandBufferImpl* context = + static_cast<WebGraphicsContext3DCommandBufferImpl*>( + web_view_->graphicsContext3D()); + if (!context) + return false; - // Make sure the nested delegate shows up in the right place - // on the page. - SendNestedDelegateGeometryToBrowser(position, clip); + ggl::Context* parent_context = context->context(); + if (!parent_context) + return false; - return true; - } - } + RenderThread* render_thread = RenderThread::current(); + if (!render_thread) + return false; - nested_delegate_->DestroyCommandBuffer(command_buffer_); - command_buffer_ = NULL; - } + GpuChannelHost* host = render_thread->GetGpuChannel(); + if (!host) + return false; - nested_delegate_->PluginDestroyed(); - nested_delegate_ = NULL; -#endif // ENABLE_GPU - return false; + DCHECK(host->state() == GpuChannelHost::CONNECTED); + + // TODO(apatrick): Let Pepper plugins configure their back buffer surface. + static const int32 attribs[] = { + ggl::GGL_ALPHA_SIZE, 8, + ggl::GGL_DEPTH_SIZE, 24, + ggl::GGL_STENCIL_SIZE, 8, + ggl::GGL_SAMPLES, 0, + ggl::GGL_SAMPLE_BUFFERS, 0, + ggl::GGL_NONE, + }; + + // TODO(apatrick): Decide which extensions to expose to Pepper plugins. + // Currently they get only core GLES2. + context_ = ggl::CreateOffscreenContext(host, + parent_context, + gfx::Size(1, 1), + "", + attribs); + if (!context_) + return false; + + return true; } -void PlatformContext3DImpl::SendNestedDelegateGeometryToBrowser( - const gfx::Rect& window_rect, - const gfx::Rect& clip_rect) { - // Inform the browser about the location of the plugin on the page. - // It appears that initially the plugin does not get laid out correctly -- - // possibly due to lazy creation of the nested delegate. - if (!nested_delegate_ || - !nested_delegate_->GetPluginWindowHandle() || - !render_view_) { - return; - } +bool PlatformContext3DImpl::SwapBuffers() { + DCHECK(context_); + return ggl::SwapBuffers(context_); +} + +unsigned PlatformContext3DImpl::GetError() { + DCHECK(context_); + return ggl::GetError(context_); +} + +void PlatformContext3DImpl::ResizeBackingTexture(const gfx::Size& size) { + DCHECK(context_); + ggl::ResizeOffscreenContext(context_, size); +} + +void PlatformContext3DImpl::SetSwapBuffersCallback(Callback0::Type* callback) { + DCHECK(context_); + ggl::SetSwapBuffersCallback(context_, callback); +} + +unsigned PlatformContext3DImpl::GetBackingTextureId() { + DCHECK(context_); + return ggl::GetParentTextureId(context_); +} - webkit_glue::WebPluginGeometry geom; - geom.window = nested_delegate_->GetPluginWindowHandle(); - geom.window_rect = window_rect; - geom.clip_rect = clip_rect; - // Rects_valid must be true for this to work in the Gtk port; - // hopefully not having the cutout rects will not cause incorrect - // clipping. - geom.rects_valid = true; - geom.visible = true; - render_view_->DidMovePlugin(geom); +gpu::gles2::GLES2Implementation* + PlatformContext3DImpl::GetGLES2Implementation() { + DCHECK(context_); + return ggl::GetImplementation(context_); } #endif // ENABLE_GPU @@ -604,7 +506,7 @@ PepperPluginDelegateImpl::CreateImage2D(int width, int height) { pepper::PluginDelegate::PlatformContext3D* PepperPluginDelegateImpl::CreateContext3D() { #ifdef ENABLE_GPU - return new PlatformContext3DImpl(render_view_); + return new PlatformContext3DImpl(render_view_->webview()); #else return NULL; #endif diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 176b1ae..7355fae8 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -86,6 +86,7 @@ #include "chrome/renderer/user_script_idle_scheduler.h" #include "chrome/renderer/user_script_slave.h" #include "chrome/renderer/visitedlink_slave.h" +#include "chrome/renderer/webgraphicscontext3d_command_buffer_impl.h" #include "chrome/renderer/webplugin_delegate_pepper.h" #include "chrome/renderer/webplugin_delegate_proxy.h" #include "chrome/renderer/websharedworker_proxy.h" @@ -2628,14 +2629,19 @@ WebMediaPlayer* RenderView::createMediaPlayer( if (cmd_line->HasSwitch(switches::kEnableAcceleratedDecoding) && !cmd_line->HasSwitch(switches::kDisableAcceleratedCompositing)) { + WebGraphicsContext3DCommandBufferImpl* context = + static_cast<WebGraphicsContext3DCommandBufferImpl*>( + frame->view()->graphicsContext3D()); + if (!context) + return NULL; + // Add the hardware video decoder factory. - // TODO(hclam): This assumes that ggl::Context is set to current - // internally. I need to make it more explicit to get the context. - bool ret = frame->view()->graphicsContext3D()->makeContextCurrent(); + // TODO(hclam): This will cause the renderer process to crash on context + // lost. + bool ret = context->makeContextCurrent(); CHECK(ret) << "Failed to switch context"; - collection->AddFilter(new IpcVideoDecoder( - MessageLoop::current(), ggl::GetCurrentContext())); + MessageLoop::current(), context->context())); } WebApplicationCacheHostImpl* appcache_host = diff --git a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h index 116bced..11369d7 100644 --- a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h +++ b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h @@ -368,6 +368,8 @@ class WebGraphicsContext3DCommandBufferImpl virtual void copyTextureToCompositor(unsigned texture, unsigned parent_texture); + ggl::Context* context() { return context_; } + private: // The GGL context we use for OpenGL rendering. ggl::Context* context_; |