diff options
author | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-25 14:47:32 +0000 |
---|---|---|
committer | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-25 14:47:32 +0000 |
commit | 5a9299c645bfa4fcbbc3b3106af2837e2b9f7ec1 (patch) | |
tree | 3a1fba0dfd544e6d0dbbebaef594dce16a8afc6e /gpu/command_buffer/service | |
parent | 05f0f84db4862d970c79839450be35d67ce7d052 (diff) | |
download | chromium_src-5a9299c645bfa4fcbbc3b3106af2837e2b9f7ec1.zip chromium_src-5a9299c645bfa4fcbbc3b3106af2837e2b9f7ec1.tar.gz chromium_src-5a9299c645bfa4fcbbc3b3106af2837e2b9f7ec1.tar.bz2 |
Use pixmaps and EGLImages to transport image data between GPU process and browser. Behind a compile TOUCH_UI flag.
It uses the MAC OSX AcceleratedSurface IPCs to communicate between the GPU process and browser. The major difference between the OSX display path is that I send an ACK back after AcceleratedSurfaceSetIOSurface because the process of binding a texture to the pixmap may destroy the contents of the pixmap.
BUG=none
TEST=by hand on Linux (w/ and w/o TOUCH_UI), Windows, and Mac
Review URL: http://codereview.chromium.org/6987014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90511 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/service')
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler.cc | 11 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler.h | 51 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler_linux.cc | 77 |
3 files changed, 123 insertions, 16 deletions
diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc index d4ac593..a67fd3a 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -25,7 +25,7 @@ GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, : command_buffer_(command_buffer), commands_per_update_(100), unscheduled_count_(0), -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(TOUCH_UI) swap_buffers_count_(0), acknowledged_swap_buffers_count_(0), #endif @@ -46,7 +46,7 @@ GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, : command_buffer_(command_buffer), commands_per_update_(commands_per_update), unscheduled_count_(0), -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(TOUCH_UI) swap_buffers_count_(0), acknowledged_swap_buffers_count_(0), #endif @@ -139,7 +139,7 @@ bool GpuScheduler::SetParent(GpuScheduler* parent_scheduler, return decoder_->SetParent(NULL, 0); } -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(TOUCH_UI) namespace { const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; } @@ -178,6 +178,11 @@ void GpuScheduler::ProcessCommands() { #if defined(OS_MACOSX) bool do_rate_limiting = surface_.get() != NULL; +#elif defined(TOUCH_UI) + bool do_rate_limiting = back_surface_.get() != NULL; +#endif + +#if defined(OS_MACOSX) || defined(TOUCH_UI) // Don't swamp the browser process with SwapBuffers calls it can't handle. if (do_rate_limiting && swap_buffers_count_ - acknowledged_swap_buffers_count_ >= diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h index 31b6a95..a5d10ae 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -5,6 +5,7 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_H_ #define GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_H_ +#include <map> #include <queue> #include <vector> @@ -23,6 +24,8 @@ #if defined(OS_MACOSX) #include "ui/gfx/surface/accelerated_surface_mac.h" +#elif defined(TOUCH_UI) +#include "ui/gfx/surface/accelerated_surface_linux.h" #endif namespace gfx { @@ -94,6 +97,19 @@ class GpuScheduler : public CommandBufferEngine { // Asynchronously resizes an offscreen frame buffer. void ResizeOffscreenFrameBuffer(const gfx::Size& size); +#if defined(OS_MACOSX) || defined(TOUCH_UI) + // To prevent the GPU process from overloading the browser process, + // we need to track the number of swap buffers calls issued and + // acknowledged per on-screen context, and keep the GPU from getting + // too far ahead of the browser. Note that this + // is also predicated on a flow control mechanism between the + // renderer and GPU processes. + uint64 swap_buffers_count() const; + uint64 acknowledged_swap_buffers_count() const; + void set_acknowledged_swap_buffers_count( + uint64 acknowledged_swap_buffers_count); +#endif + #if defined(OS_MACOSX) // Needed only on Mac OS X, which does not render into an on-screen // window and therefore requires the backing store to be resized @@ -107,22 +123,23 @@ class GpuScheduler : public CommandBufferEngine { virtual void SetTransportDIBAllocAndFree( Callback2<size_t, TransportDIB::Handle*>::Type* allocator, Callback1<TransportDIB::Id>::Type* deallocator); - // Returns the id of the current IOSurface, or 0. + // Returns the id of the current surface that is being rendered to + // (or 0 if no such surface has been created). virtual uint64 GetSurfaceId(); - // To prevent the GPU process from overloading the browser process, - // we need to track the number of swap buffers calls issued and - // acknowledged per on-screen (IOSurface-backed) context, and keep - // the GPU from getting too far ahead of the browser. Note that this - // is also predicated on a flow control mechanism between the - // renderer and GPU processes. - uint64 swap_buffers_count() const; - uint64 acknowledged_swap_buffers_count() const; - void set_acknowledged_swap_buffers_count( - uint64 acknowledged_swap_buffers_count); void DidDestroySurface(); #endif +#if defined(TOUCH_UI) + virtual void CreateBackSurface(const gfx::Size& size); + // Should not be back_surface_ or front_surface_. + virtual void ReleaseSurface(uint64 surface_id); + + // Returns the id of the surface (or 0 if no such surface has been created). + virtual uint64 GetBackSurfaceId(); + virtual uint64 GetFrontSurfaceId(); +#endif + // Sets a callback that is called when a glResizeCHROMIUM command // is processed. void SetResizeCallback(Callback1<gfx::Size>::Type* callback); @@ -183,12 +200,20 @@ class GpuScheduler : public CommandBufferEngine { scoped_ptr<Callback0::Type> scheduled_callback_; -#if defined(OS_MACOSX) - scoped_ptr<AcceleratedSurface> surface_; +#if defined(OS_MACOSX) || defined(TOUCH_UI) uint64 swap_buffers_count_; uint64 acknowledged_swap_buffers_count_; #endif +#if defined(OS_MACOSX) + scoped_ptr<AcceleratedSurface> surface_; +#elif defined(TOUCH_UI) + std::map<uint64, scoped_refptr<AcceleratedSurface> > + surfaces_; + scoped_refptr<AcceleratedSurface> back_surface_; + scoped_refptr<AcceleratedSurface> front_surface_; +#endif + ScopedRunnableMethodFactory<GpuScheduler> method_factory_; scoped_ptr<Callback1<gfx::Size>::Type> wrapped_resize_callback_; scoped_ptr<Callback0::Type> wrapped_swap_buffers_callback_; diff --git a/gpu/command_buffer/service/gpu_scheduler_linux.cc b/gpu/command_buffer/service/gpu_scheduler_linux.cc index 6adaba6..1c6c8e9 100644 --- a/gpu/command_buffer/service/gpu_scheduler_linux.cc +++ b/gpu/command_buffer/service/gpu_scheduler_linux.cc @@ -7,6 +7,13 @@ #include "ui/gfx/gl/gl_share_group.h" #include "ui/gfx/gl/gl_surface.h" +#if defined(TOUCH_UI) +#include "third_party/angle/include/EGL/egl.h" +#include "third_party/angle/include/EGL/eglext.h" +#include "ui/gfx/gl/gl_surface_egl.h" +#include "ui/gfx/gl/gl_bindings.h" +#endif + using ::base::SharedMemory; namespace gpu { @@ -20,10 +27,14 @@ bool GpuScheduler::Initialize( gfx::GLShareGroup* share_group) { // Create either a view or pbuffer based GLSurface. scoped_refptr<gfx::GLSurface> surface; +#if defined(TOUCH_UI) + surface = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); +#else if (window) surface = gfx::GLSurface::CreateViewGLSurface(window); else surface = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); +#endif if (!surface.get()) { LOG(ERROR) << "GpuScheduler::Initialize failed.\n"; @@ -53,9 +64,75 @@ void GpuScheduler::Destroy() { } void GpuScheduler::WillSwapBuffers() { +#if defined(TOUCH_UI) + front_surface_.swap(back_surface_); + DCHECK_NE(front_surface_.get(), static_cast<AcceleratedSurface*>(NULL)); + + gfx::Size expected_size = front_surface_->size(); + if (!back_surface_.get() || back_surface_->size() != expected_size) { + wrapped_resize_callback_->Run(expected_size); + } else { + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + back_surface_->texture(), + 0); + } + ++swap_buffers_count_; + glFlush(); +#endif if (wrapped_swap_buffers_callback_.get()) { wrapped_swap_buffers_callback_->Run(); } } +#if defined(TOUCH_UI) +uint64 GpuScheduler::GetBackSurfaceId() { + if (!back_surface_.get()) + return 0; + return back_surface_->pixmap(); +} + +uint64 GpuScheduler::GetFrontSurfaceId() { + if (!front_surface_.get()) + return 0; + return front_surface_->pixmap(); +} + +uint64 GpuScheduler::swap_buffers_count() const { + return swap_buffers_count_; +} + +uint64 GpuScheduler::acknowledged_swap_buffers_count() const { + return acknowledged_swap_buffers_count_; +} + +void GpuScheduler::set_acknowledged_swap_buffers_count( + uint64 acknowledged_swap_buffers_count) { + acknowledged_swap_buffers_count_ = acknowledged_swap_buffers_count; +} + +void GpuScheduler::CreateBackSurface(const gfx::Size& size) { + decoder()->ResizeOffscreenFrameBuffer(size); + decoder()->UpdateOffscreenFrameBufferSize(); + + back_surface_ = new AcceleratedSurface(size); + surfaces_[back_surface_->pixmap()] = back_surface_; + + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + back_surface_->texture(), + 0); + glFlush(); +} + +void GpuScheduler::ReleaseSurface(uint64 surface_id) { + DCHECK_NE(surfaces_[surface_id].get(), back_surface_.get()); + DCHECK_NE(surfaces_[surface_id].get(), front_surface_.get()); + surfaces_.erase(surface_id); +} + +#endif + } // namespace gpu |