summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service
diff options
context:
space:
mode:
authorbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-25 14:47:32 +0000
committerbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-25 14:47:32 +0000
commit5a9299c645bfa4fcbbc3b3106af2837e2b9f7ec1 (patch)
tree3a1fba0dfd544e6d0dbbebaef594dce16a8afc6e /gpu/command_buffer/service
parent05f0f84db4862d970c79839450be35d67ce7d052 (diff)
downloadchromium_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.cc11
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.h51
-rw-r--r--gpu/command_buffer/service/gpu_scheduler_linux.cc77
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