diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-12 21:24:24 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-12 21:24:24 +0000 |
commit | 48a5faa6500b6c6055348abf1540cbb06c721f33 (patch) | |
tree | 043ab3baeec17a93ee2bcee1c23e92f3d608a4e9 /ppapi/proxy/ppb_graphics_2d_proxy.cc | |
parent | b7a4f36aa4ac90259978a7bdf83288e6889fbc83 (diff) | |
download | chromium_src-48a5faa6500b6c6055348abf1540cbb06c721f33.zip chromium_src-48a5faa6500b6c6055348abf1540cbb06c721f33.tar.gz chromium_src-48a5faa6500b6c6055348abf1540cbb06c721f33.tar.bz2 |
Make the Graphics2D flush call an asynchronous operation. This tracks the
callback in the plugin and adds a new message when a flush is complete in
the renderer.
I adapted the callback factory so it could be used for tracking the flush
callbacks in the proxy in the renderer, and also changed the URL loader
stuff (which had some custom management) around so that it also uses the
factory.
This also fixes a bug in font proxying where we would assert if there was a
font creation error because the dispatcher wasn't set on the SerializedVar in
the font decription.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/4876003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65995 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy/ppb_graphics_2d_proxy.cc')
-rw-r--r-- | ppapi/proxy/ppb_graphics_2d_proxy.cc | 90 |
1 files changed, 72 insertions, 18 deletions
diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.cc b/ppapi/proxy/ppb_graphics_2d_proxy.cc index 0567369..74f8b91 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_2d_proxy.cc @@ -4,8 +4,9 @@ #include "ppapi/proxy/ppb_graphics_2d_proxy.h" -#include <string.h> // For memset +#include <string.h> // For memset. +#include "base/compiler_specific.h" #include "base/logging.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" @@ -21,7 +22,9 @@ namespace proxy { class Graphics2D : public PluginResource { public: Graphics2D(const PP_Size& size, PP_Bool is_always_opaque) - : size_(size), is_always_opaque_(is_always_opaque) { + : size_(size), + is_always_opaque_(is_always_opaque), + current_flush_callback_(PP_BlockUntilComplete()) { } // Resource overrides. @@ -30,10 +33,23 @@ class Graphics2D : public PluginResource { const PP_Size& size() const { return size_; } PP_Bool is_always_opaque() const { return is_always_opaque_; } + bool is_flush_pending() const { return !!current_flush_callback_.func; } + + PP_CompletionCallback current_flush_callback() const { + return current_flush_callback_; + } + void set_current_flush_callback(PP_CompletionCallback cb) { + current_flush_callback_ = cb; + } + private: PP_Size size_; PP_Bool is_always_opaque_; + // In the plugin, this is the current callback set for Flushes. When the + // callback function pointer is non-NULL, we're waiting for a flush ACK. + PP_CompletionCallback current_flush_callback_; + DISALLOW_COPY_AND_ASSIGN(Graphics2D); }; @@ -103,13 +119,22 @@ void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) { int32_t Flush(PP_Resource graphics_2d, PP_CompletionCallback callback) { - PluginDispatcher* dispatcher = PluginDispatcher::Get(); - int32_t result = PP_ERROR_FAILED; - dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Flush( - INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, - dispatcher->callback_tracker().SendCallback(callback), - &result)); - return result; + Graphics2D* object = PluginResource::GetAs<Graphics2D>(graphics_2d); + if (!object) + return PP_ERROR_BADRESOURCE; + + // For now, disallow blocking calls. We'll need to add support for other + // threads to this later. + if (!callback.func) + return PP_ERROR_BADARGUMENT; + + if (object->is_flush_pending()) + return PP_ERROR_INPROGRESS; // Can't have >1 flush pending. + object->set_current_flush_callback(callback); + + PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBGraphics2D_Flush( + INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d)); + return PP_ERROR_WOULDBLOCK; } const PPB_Graphics2D ppb_graphics_2d = { @@ -126,7 +151,8 @@ const PPB_Graphics2D ppb_graphics_2d = { PPB_Graphics2D_Proxy::PPB_Graphics2D_Proxy(Dispatcher* dispatcher, const void* target_interface) - : InterfaceProxy(dispatcher, target_interface) { + : InterfaceProxy(dispatcher, target_interface), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { } PPB_Graphics2D_Proxy::~PPB_Graphics2D_Proxy() { @@ -152,6 +178,9 @@ void PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) { OnMsgReplaceContents) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_Flush, OnMsgFlush) + + IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics2D_FlushACK, + OnMsgFlushACK) IPC_END_MESSAGE_MAP() // FIXME(brettw) handle bad messages! } @@ -188,14 +217,39 @@ void PPB_Graphics2D_Proxy::OnMsgReplaceContents(PP_Resource graphics_2d, ppb_graphics_2d_target()->ReplaceContents(graphics_2d, image_data); } -void PPB_Graphics2D_Proxy::OnMsgFlush(PP_Resource graphics_2d, - uint32_t serialized_callback, - int32_t* result) { - // TODO(brettw) this should be a non-sync function. Ideally it would call - // the callback with a failure code from here if you weren't allowed to - // call Flush there. - *result = ppb_graphics_2d_target()->Flush( - graphics_2d, ReceiveCallback(serialized_callback)); +void PPB_Graphics2D_Proxy::OnMsgFlush(PP_Resource graphics_2d) { + CompletionCallback callback = callback_factory_.NewCallback( + &PPB_Graphics2D_Proxy::SendFlushACKToPlugin, graphics_2d); + int32_t result = ppb_graphics_2d_target()->Flush( + graphics_2d, callback.pp_completion_callback()); + if (result != PP_ERROR_WOULDBLOCK) { + // There was some error, so we won't get a flush callback. We need to now + // issue the ACK to the plugin hears about the error. This will also clean + // up the data associated with the callback. + callback.Run(result); + } +} + +void PPB_Graphics2D_Proxy::OnMsgFlushACK(PP_Resource resource, + int32_t pp_error) { + Graphics2D* object = PluginResource::GetAs<Graphics2D>(resource); + if (!object) { + // The plugin has released the graphics 2D object so don't issue the + // callback. + return; + } + + // Be careful to make the callback NULL again before issuing the callback + // since the plugin might want to flush from within the callback. + PP_CompletionCallback callback = object->current_flush_callback(); + object->set_current_flush_callback(PP_BlockUntilComplete()); + PP_RunCompletionCallback(&callback, pp_error); +} + +void PPB_Graphics2D_Proxy::SendFlushACKToPlugin(int32_t result, + PP_Resource graphics_2d) { + dispatcher()->Send(new PpapiMsg_PPBGraphics2D_FlushACK( + INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, result)); } } // namespace proxy |