summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-08 20:19:44 +0000
committerajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-08 20:19:44 +0000
commitf51ffcf1fa06f12c96cc3bcb6c0659c65371fe81 (patch)
tree73cf0fc1db209096852914e7ea719d217cf0ad08
parent482a2662398a751f1a231b1ef84f19de91ee3764 (diff)
downloadchromium_src-f51ffcf1fa06f12c96cc3bcb6c0659c65371fe81.zip
chromium_src-f51ffcf1fa06f12c96cc3bcb6c0659c65371fe81.tar.gz
chromium_src-f51ffcf1fa06f12c96cc3bcb6c0659c65371fe81.tar.bz2
Revert r51857 "Integrating back into using the external ppapi/cpp wrappers."
For some reason, this looks like it breaks all PPAPI ui tests on linux. TBR: tonyg git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51885 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--remoting/client/chromoting_client.cc10
-rw-r--r--remoting/client/chromoting_client.h4
-rw-r--r--remoting/client/plugin/chromoting_plugin.cc82
-rw-r--r--remoting/client/plugin/chromoting_plugin.h38
-rw-r--r--remoting/client/plugin/pepper_entrypoints.cc235
-rw-r--r--remoting/client/plugin/pepper_util.cc31
-rw-r--r--remoting/client/plugin/pepper_util.h32
-rw-r--r--remoting/client/plugin/pepper_view.cc231
-rw-r--r--remoting/client/plugin/pepper_view.h51
-rw-r--r--remoting/remoting.gyp5
10 files changed, 390 insertions, 329 deletions
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc
index 39f18b4..cad1993 100644
--- a/remoting/client/chromoting_client.cc
+++ b/remoting/client/chromoting_client.cc
@@ -8,9 +8,9 @@
#include "remoting/client/chromoting_view.h"
#include "remoting/client/host_connection.h"
-static const uint32 kCreatedColor = 0xffccccff;
-static const uint32 kDisconnectedColor = 0xff00ccff;
-static const uint32 kFailedColor = 0xffcc00ff;
+static const uint32 kCreatedColor = 0xff0000ff;
+static const uint32 kDisconnectedColor = 0xff00ff00;
+static const uint32 kFailedColor = 0xffff0000;
namespace remoting {
@@ -162,9 +162,9 @@ void ChromotingClient::DoHandleUpdate(HostMessage* msg) {
void ChromotingClient::DoEndUpdate(HostMessage* msg) {
DCHECK_EQ(message_loop(), MessageLoop::current());
- DCHECK(msg->has_end_update_stream());
+ DCHECK(msg->has_update_stream_packet());
- view_->HandleEndUpdateStream(msg);
+ view_->HandleUpdateStreamPacket(msg);
}
} // namespace remoting
diff --git a/remoting/client/chromoting_client.h b/remoting/client/chromoting_client.h
index 50cc0dc..587f1fb 100644
--- a/remoting/client/chromoting_client.h
+++ b/remoting/client/chromoting_client.h
@@ -28,10 +28,6 @@ class ChromotingClient : public HostConnection::HostEventCallback {
// Sets the viewport to do display. The viewport may be larger and/or
// smaller than the actual image background being displayed.
- //
- // TODO(ajwong): This doesn't make sense to have here. We're going to have
- // threading isseus since pepper view needs to be called from the main pepper
- // thread synchronously really.
virtual void SetViewport(int x, int y, int width, int height);
// HostConnection::HostEventCallback implementation.
diff --git a/remoting/client/plugin/chromoting_plugin.cc b/remoting/client/plugin/chromoting_plugin.cc
index 84dfe32..c5b5b03 100644
--- a/remoting/client/plugin/chromoting_plugin.cc
+++ b/remoting/client/plugin/chromoting_plugin.cc
@@ -7,7 +7,6 @@
#include <string>
#include <vector>
-#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/thread.h"
#include "remoting/client/chromoting_client.h"
@@ -18,6 +17,7 @@
#include "third_party/ppapi/c/pp_event.h"
#include "third_party/ppapi/c/pp_rect.h"
#include "third_party/ppapi/cpp/completion_callback.h"
+#include "third_party/ppapi/cpp/image_data.h"
using std::string;
using std::vector;
@@ -26,9 +26,13 @@ namespace remoting {
const char* ChromotingPlugin::kMimeType = "pepper-application/x-chromoting";
-ChromotingPlugin::ChromotingPlugin(PP_Instance pp_instance)
- : pp::Instance(pp_instance),
- pepper_main_loop_dont_post_to_me_(NULL) {
+ChromotingPlugin::ChromotingPlugin(PP_Instance pp_instance,
+ const PPB_Instance* ppb_instance_funcs)
+ : width_(0),
+ height_(0),
+ drawing_context_(NULL),
+ pp_instance_(pp_instance),
+ ppb_instance_funcs_(ppb_instance_funcs) {
}
ChromotingPlugin::~ChromotingPlugin() {
@@ -49,19 +53,6 @@ ChromotingPlugin::~ChromotingPlugin() {
bool ChromotingPlugin::Init(uint32_t argc,
const char* argn[],
const char* argv[]) {
- CHECK(pepper_main_loop_dont_post_to_me_ == NULL);
-
- // Record the current thread. This function should only be invoked by the
- // plugin thread, so we capture the current message loop and assume it is
- // indeed the plugin thread.
- //
- // We're abusing the pepper API slightly here. We know we're running as an
- // internal plugin, and thus we are on the pepper main thread that uses a
- // message loop.
- //
- // TODO(ajwong): See if there is a method for querying what thread we're on
- // from inside the pepper API.
- pepper_main_loop_dont_post_to_me_ = MessageLoop::current();
LOG(INFO) << "Started ChromotingPlugin::Init";
// Extract the URL from the arguments.
@@ -96,23 +87,21 @@ bool ChromotingPlugin::Init(uint32_t argc,
// Create the chromting objects.
host_connection_.reset(new JingleHostConnection(network_thread_.get()));
- view_.reset(new PepperView(this));
- client_.reset(new ChromotingClient(main_thread_->message_loop(),
- host_connection_.get(), view_.get()));
-
- // Default to a medium grey.
- view_->SetSolidFill(0xFFCDCDCD);
+ /*
+ view_.reset(new PepperView(main_thread_->message_loop(), device_,
+ instance()));
+ */
+ //client_.reset(new ChromotingClient(main_thread_->message_loop(),
+ // host_connection_.get(), view_.get()));
// Kick off the connection.
- host_connection_->Connect(user_id, auth_token, host_jid, client_.get());
+ //host_connection_->Connect(user_id, auth_token, host_jid, client_.get());
return true;
}
void ChromotingPlugin::ViewChanged(const PP_Rect& position,
const PP_Rect& clip) {
- DCHECK(CurrentlyOnPluginThread());
-
// TODO(ajwong): This is going to be a race condition when the view changes
// and we're in the middle of a Paint().
LOG(INFO) << "ViewChanged "
@@ -121,18 +110,43 @@ void ChromotingPlugin::ViewChanged(const PP_Rect& position,
<< position.size.width << ","
<< position.size.height;
- view_->SetViewport(position.point.x, position.point.y,
- position.size.width, position.size.height);
- view_->Paint();
-}
+ // TODO(ajwong): Do we care about the position? Probably not...
+ if (position.size.width == width_ || position.size.height == height_)
+ return;
+
+ width_ = position.size.width;
+ height_ = position.size.height;
+
+ /*
+ * TODO(ajwong): Reenable this code once we fingure out how we want to
+ * abstract away the C-api for DeviceContext2D.
+ device_context_ = pp::DeviceContext2D(width_, height_, false);
+ if (!ppb_instance_funcs_->BindGraphicsDeviceContext(
+ pp_instance_,
+ device_context_.pp_resource())) {
+ LOG(ERROR) << "Couldn't bind the device context.";
+ return;
+ }
-bool ChromotingPlugin::CurrentlyOnPluginThread() const {
- return pepper_main_loop_dont_post_to_me_ == MessageLoop::current();
+ pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width_, height_, false);
+ if (!image.is_null()) {
+ for (int y = 0; y < image.height(); y++) {
+ for (int x = 0; x < image.width(); x++) {
+ *image.GetAddr32(x, y) = 0xccff00cc;
+ }
+ }
+ device_context_.ReplaceContents(&image);
+ device_context_.Flush(pp::CompletionCallback(NULL, this));
+ } else {
+ LOG(ERROR) << "Unable to allocate image.";
+ }
+ */
+
+ //client_->SetViewport(0, 0, width_, height_);
+ //client_->Repaint();
}
bool ChromotingPlugin::HandleEvent(const PP_Event& event) {
- DCHECK(CurrentlyOnPluginThread());
-
switch (event.type) {
case PP_Event_Type_MouseDown:
case PP_Event_Type_MouseUp:
diff --git a/remoting/client/plugin/chromoting_plugin.h b/remoting/client/plugin/chromoting_plugin.h
index 0aac051..757e038 100644
--- a/remoting/client/plugin/chromoting_plugin.h
+++ b/remoting/client/plugin/chromoting_plugin.h
@@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// TODO(ajwong): We need to come up with a better description of the
-// responsibilities for each thread.
-
#ifndef REMOTING_CLIENT_PLUGIN_CHROMOTING_PLUGIN_H_
#define REMOTING_CLIENT_PLUGIN_CHROMOTING_PLUGIN_H_
@@ -18,19 +15,12 @@
#include "third_party/ppapi/c/pp_instance.h"
#include "third_party/ppapi/c/pp_rect.h"
#include "third_party/ppapi/c/pp_resource.h"
-#include "third_party/ppapi/cpp/instance.h"
-#include "third_party/ppapi/cpp/device_context_2d.h"
-
-class MessageLoop;
+#include "third_party/ppapi/c/ppb_instance.h"
namespace base {
class Thread;
} // namespace base
-namespace pp {
-class Module;
-} // namespace pp
-
namespace remoting {
class ChromotingClient;
@@ -38,20 +28,23 @@ class HostConnection;
class JingleThread;
class PepperView;
-class ChromotingPlugin : public pp::Instance {
+class ChromotingClient;
+
+class ChromotingPlugin {
public:
// The mimetype for which this plugin is registered.
+ //
+ // TODO(ajwong): Mimetype doesn't really make sense for us as the trigger
+ // point. I think we should handle a special protocol (eg., chromotocol://)
static const char *kMimeType;
- ChromotingPlugin(PP_Instance instance);
+ ChromotingPlugin(PP_Instance instance, const PPB_Instance* instance_funcs);
virtual ~ChromotingPlugin();
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
virtual bool HandleEvent(const PP_Event& event);
virtual void ViewChanged(const PP_Rect& position, const PP_Rect& clip);
- virtual bool CurrentlyOnPluginThread() const;
-
private:
FRIEND_TEST(ChromotingPluginTest, ParseUrl);
FRIEND_TEST(ChromotingPluginTest, TestCaseSetup);
@@ -61,13 +54,14 @@ class ChromotingPlugin : public pp::Instance {
std::string* auth_token,
std::string* host_jid);
- // Since we're an internal plugin, we can just grab the message loop during
- // init to figure out which thread we're on. This should only be used to
- // sanity check which thread we're executing on. Do not post task here!
- // Instead, use PPB_Core:CallOnMainThread() in the pepper api.
- //
- // TODO(ajwong): Think if there is a better way to safeguard this.
- MessageLoop* pepper_main_loop_dont_post_to_me_;
+ // Size of the plugin window.
+ int width_;
+ int height_;
+
+ PP_Resource drawing_context_;
+
+ PP_Instance pp_instance_;
+ const PPB_Instance* ppb_instance_funcs_;
scoped_ptr<base::Thread> main_thread_;
scoped_ptr<JingleThread> network_thread_;
diff --git a/remoting/client/plugin/pepper_entrypoints.cc b/remoting/client/plugin/pepper_entrypoints.cc
index bd69863..c8a0895 100644
--- a/remoting/client/plugin/pepper_entrypoints.cc
+++ b/remoting/client/plugin/pepper_entrypoints.cc
@@ -4,59 +4,236 @@
#include "remoting/client/plugin/pepper_entrypoints.h"
-#include "base/message_loop.h"
#include "remoting/client/plugin/chromoting_plugin.h"
-#include "third_party/ppapi/c/pp_errors.h"
#include "third_party/ppapi/c/pp_instance.h"
#include "third_party/ppapi/c/pp_module.h"
-#include "third_party/ppapi/c/ppb_instance.h"
+#include "third_party/ppapi/c/ppp_instance.h"
#include "third_party/ppapi/cpp/instance.h"
#include "third_party/ppapi/cpp/module.h"
-static pp::Module* g_module_singleton = NULL;
+static const int kModuleInitSuccess = 0;
+static const int kModuleInitFailure = 1;
-namespace pp {
+namespace remoting {
-Module* Module::Get() {
- return g_module_singleton;
-}
+// Fork of ppapi::Module
+//
+// TODO(ajwong): Generalize this into something that other internal plugins can
+// use. Either that, or attempt to refactor the external ppapi C++ wrapper to
+// make it friendly for multiple Modules in one process. I think we can do this
+// by:
+// 1) Moving the singleton Module instance + C-bindings into another class
+// (eg., ModuleExporter) under a different gyp targe.
+// 2) Extracting the idea of a "Browser" out of the module that returns
+// PPB_Core, etc. This can be a singleton per process regardless of
+// module.
+// 3) Migrate all PPB related objects to get data out of Browser interface
+// instead of Module::Get().
+class ChromotingModule {
+ public:
+ ChromotingModule() {}
-} // namespace pp
+ // This function will be automatically called after the object is created.
+ // This is where you can put functions that rely on other parts of the API,
+ // now that the module has been created.
+ virtual bool Init() { return true; }
-namespace remoting {
+ PP_Module pp_module() const { return pp_module_; }
+ const PPB_Core& core() const { return *core_; }
+
+ // Implements GetInterface for the browser to get plugin interfaces. Override
+ // if you need to implement your own interface types that this wrapper
+ // doesn't support.
+ virtual const void* GetInstanceInterface(const char* interface_name) {
+ if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
+ return &instance_interface_;
+
+ return NULL;
+ }
+
+ // Returns an interface in the browser.
+ const void* GetBrowserInterface(const char* interface_name) {
+ return get_browser_interface_(interface_name);
+ }
+
+ // Returns the object associated with this PP_Instance, or NULL if one is
+ // not found.
+ ChromotingPlugin* InstanceForPPInstance(PP_Instance instance) {
+ InstanceMap::iterator found = current_instances_.find(instance);
+ if (found == current_instances_.end())
+ return NULL;
+ return found->second;
+ }
+
+ // Sets the browser interface and calls the regular init function that
+ // can be overridden by the base classes.
+ //
+ // TODO(brettw) make this private when I can figure out how to make the
+ // initialize function a friend.
+ bool InternalInit(PP_Module mod,
+ PPB_GetInterface get_browser_interface) {
+ pp_module_ = mod;
+ get_browser_interface_ = get_browser_interface;
+ core_ = reinterpret_cast<const PPB_Core*>(GetBrowserInterface(
+ PPB_CORE_INTERFACE));
+ if (!core_)
+ return false; // Can't run without the core interface.
+
+ return Init();
+ }
+
+ // Implementation of Global PPP functions ---------------------------------
+ static int PPP_InitializeModule(PP_Module module_id,
+ PPB_GetInterface get_browser_interface) {
+ ChromotingModule* module = new ChromotingModule();
+ if (!module)
+ return kModuleInitFailure;
+
+ if (!module->InternalInit(module_id, get_browser_interface)) {
+ delete module;
+ return kModuleInitFailure;
+ }
+
+ module_singleton_ = module;
+ return kModuleInitSuccess;
+ }
+
+ static void PPP_ShutdownModule() {
+ delete module_singleton_;
+ module_singleton_ = NULL;
+ }
+
+ static const void* PPP_GetInterface(const char* interface_name) {
+ if (!module_singleton_)
+ return NULL;
+ return module_singleton_->GetInstanceInterface(interface_name);
+ }
-class ChromotingModule : public pp::Module {
protected:
virtual ChromotingPlugin* CreateInstance(PP_Instance instance) {
- return new ChromotingPlugin(instance);
+ const PPB_Instance* ppb_instance_funcs =
+ reinterpret_cast<const PPB_Instance *>(
+ module_singleton_->GetBrowserInterface(PPB_INSTANCE_INTERFACE));
+ return new ChromotingPlugin(instance, ppb_instance_funcs);
}
-};
-// Implementation of Global PPP functions ---------------------------------
-int32_t PPP_InitializeModule(PP_Module module_id,
- PPB_GetInterface get_browser_interface) {
- ChromotingModule* module = new ChromotingModule();
- if (!module)
- return PP_Error_Failed;
+ private:
+ static bool Instance_New(PP_Instance instance) {
+ if (!module_singleton_)
+ return false;
+ ChromotingPlugin* obj = module_singleton_->CreateInstance(instance);
+ if (obj) {
+ module_singleton_->current_instances_[instance] = obj;
+ return true;
+ }
+ return false;
+ }
+
+ static void Instance_Delete(PP_Instance instance) {
+ if (!module_singleton_)
+ return;
+ ChromotingModule::InstanceMap::iterator found =
+ module_singleton_->current_instances_.find(instance);
+ if (found == module_singleton_->current_instances_.end())
+ return;
+
+ // Remove it from the map before deleting to try to catch reentrancy.
+ ChromotingPlugin* obj = found->second;
+ module_singleton_->current_instances_.erase(found);
+ delete obj;
+ }
+
+ static bool Instance_Initialize(PP_Instance pp_instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ if (!module_singleton_)
+ return false;
+ ChromotingPlugin* instance =
+ module_singleton_->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return false;
+ return instance->Init(argc, argn, argv);
+ }
+
+ static bool Instance_HandleDocumentLoad(PP_Instance pp_instance,
+ PP_Resource url_loader) {
+ return false;
+ }
- if (!module->InternalInit(module_id, get_browser_interface)) {
- delete module;
- return PP_Error_Failed;
+ static bool Instance_HandleEvent(PP_Instance pp_instance,
+ const PP_Event* event) {
+ if (!module_singleton_)
+ return false;
+ ChromotingPlugin* instance =
+ module_singleton_->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return false;
+ return instance->HandleEvent(*event);
}
- g_module_singleton = module;
- return PP_OK;
+ static PP_Var Instance_GetInstanceObject(PP_Instance pp_instance) {
+ PP_Var var;
+ var.type = PP_VarType_Void;
+ return var;
+ }
+
+ static void Instance_ViewChanged(PP_Instance pp_instance,
+ const PP_Rect* position,
+ const PP_Rect* clip) {
+ if (!module_singleton_)
+ return;
+ ChromotingPlugin* instance =
+ module_singleton_->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return;
+ instance->ViewChanged(*position, *clip);
+ }
+
+ // Bindings and identifiers to and from the browser.
+ PP_Module pp_module_;
+ PPB_GetInterface get_browser_interface_;
+ PPB_Core const* core_;
+
+ // Instance tracking.
+ typedef std::map<PP_Instance, ChromotingPlugin*> InstanceMap;
+ InstanceMap current_instances_;
+
+ // Static members for the ppapi C-bridge.
+ static PPP_Instance instance_interface_;
+ static ChromotingModule* module_singleton_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromotingModule);
+};
+
+ChromotingModule* ChromotingModule::module_singleton_ = NULL;
+
+PPP_Instance ChromotingModule::instance_interface_ = {
+ &ChromotingModule::Instance_New,
+ &ChromotingModule::Instance_Delete,
+ &ChromotingModule::Instance_Initialize,
+ &ChromotingModule::Instance_HandleDocumentLoad,
+ &ChromotingModule::Instance_HandleEvent,
+ &ChromotingModule::Instance_GetInstanceObject,
+ &ChromotingModule::Instance_ViewChanged,
+};
+
+// Implementation of Global PPP functions ---------------------------------
+//
+// TODO(ajwong): This is to get around friending issues. Fix it after we decide
+// whether or not ChromotingModule should be generalized.
+int PPP_InitializeModule(PP_Module module_id,
+ PPB_GetInterface get_browser_interface) {
+ return ChromotingModule::PPP_InitializeModule(module_id,
+ get_browser_interface);
}
void PPP_ShutdownModule() {
- delete pp::Module::Get();
- g_module_singleton = NULL;
+ return ChromotingModule::PPP_ShutdownModule();
}
const void* PPP_GetInterface(const char* interface_name) {
- if (!pp::Module::Get())
- return NULL;
- return pp::Module::Get()->GetInstanceInterface(interface_name);
+ return ChromotingModule::PPP_GetInterface(interface_name);
}
} // namespace remoting
diff --git a/remoting/client/plugin/pepper_util.cc b/remoting/client/plugin/pepper_util.cc
deleted file mode 100644
index 7c91233..0000000
--- a/remoting/client/plugin/pepper_util.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "remoting/client/plugin/pepper_util.h"
-
-#include "base/task.h"
-#include "third_party/ppapi/c/pp_completion_callback.h"
-#include "third_party/ppapi/cpp/module.h"
-
-namespace remoting {
-
-void CompletionCallbackTaskAdapter(void* user_data, int32_t not_used) {
- Task* task = reinterpret_cast<Task*>(user_data);
- task->Run();
- delete task;
-}
-
-pp::CompletionCallback TaskToCompletionCallback(Task* task) {
- return pp::CompletionCallback(&CompletionCallbackTaskAdapter, task);
-}
-
-void RunTaskOnPluginThread(Task* task) {
- pp::Module::Get()->core()->CallOnMainThread(
- 0 /* run immediately */,
- TaskToCompletionCallback(task),
- 0 /* unused value */
- );
-}
-
-} // namespace remoting
diff --git a/remoting/client/plugin/pepper_util.h b/remoting/client/plugin/pepper_util.h
deleted file mode 100644
index 6c6cfb0..0000000
--- a/remoting/client/plugin/pepper_util.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2010 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.
-
-#ifndef REMOTING_CLIENT_PLUGIN_PLUGIN_UTIL_H_
-#define REMOTING_CLIENT_PLUGIN_PLUGIN_UTIL_H_
-
-#include "base/basictypes.h"
-
-#include "third_party/ppapi/cpp/completion_callback.h"
-
-class Task;
-
-namespace remoting {
-
-// Function for adapting a Chromium style Task into a
-// PP_CompletionCallback friendly function. The Task object should be passed
-// as |user_data|. This function will invoke Task::Run() on |user_data| when
-// called, and then delete |user_data|.
-void CompletionCallbackTaskAdapter(void* user_data, int32_t not_used);
-
-// Converts a Task* to a pp::CompletionCallback suitable for use with ppapi C++
-// APIs that require a pp::CompletionCallback. Takes ownership of |task|.
-pp::CompletionCallback TaskToCompletionCallback(Task* task);
-
-// Posts the current task to the plugin's main thread. Takes ownership of
-// |task|.
-void RunTaskOnPluginThread(Task* task);
-
-} // namespace remoting
-
-#endif // REMOTING_CLIENT_PLUGIN_PLUGIN_UTIL_H_
diff --git a/remoting/client/plugin/pepper_view.cc b/remoting/client/plugin/pepper_view.cc
index f638df0..d66624b5 100644
--- a/remoting/client/plugin/pepper_view.cc
+++ b/remoting/client/plugin/pepper_view.cc
@@ -6,15 +6,14 @@
#include "base/message_loop.h"
#include "remoting/client/decoder_verbatim.h"
-#include "remoting/client/plugin/chromoting_plugin.h"
-#include "remoting/client/plugin/pepper_util.h"
-#include "third_party/ppapi/cpp/device_context_2d.h"
-#include "third_party/ppapi/cpp/image_data.h"
namespace remoting {
-PepperView::PepperView(ChromotingPlugin* plugin)
- : plugin_(plugin),
+PepperView::PepperView(MessageLoop* message_loop, NPDevice* rendering_device,
+ NPP plugin_instance)
+ : message_loop_(message_loop),
+ rendering_device_(rendering_device),
+ plugin_instance_(plugin_instance),
backing_store_width_(0),
backing_store_height_(0),
viewport_x_(0),
@@ -29,173 +28,127 @@ PepperView::~PepperView() {
}
void PepperView::Paint() {
- if (!plugin_->CurrentlyOnPluginThread()) {
- RunTaskOnPluginThread(NewRunnableMethod(this, &PepperView::Paint));
- return;
- }
-
- // TODO(ajwong): We shouldn't assume the image data format.
- pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL, viewport_width_,
- viewport_height_, false);
- if (image.is_null()) {
- LOG(ERROR) << "Unable to allocate image.";
- return;
- }
-
- if (is_static_fill_) {
- for (int y = 0; y < image.height(); y++) {
- for (int x = 0; x < image.width(); x++) {
- *image.GetAddr32(x, y) = static_fill_color_;
- }
- }
- } else if (frame_) {
- int32_t* frame_data =
- reinterpret_cast<int32_t*>(frame_->data(media::VideoFrame::kRGBPlane));
- int max_height = std::min(backing_store_height_, image.height());
- int max_width = std::min(backing_store_width_, image.width());
- for (int y = 0; y < max_height; y++) {
- for (int x = 0; x < max_width; x++) {
- // Force alpha to be set to 255.
- *image.GetAddr32(x, y) =
- frame_data[y*backing_store_width_ + x] | 0xFF000000;
- }
- }
- } else {
- // Nothing to paint. escape!
- //
- // TODO(ajwong): This is an ugly control flow. fix.
- return;
- }
- device_context_.ReplaceContents(&image);
- device_context_.Flush(TaskToCompletionCallback(
- NewRunnableMethod(this, &PepperView::OnPaintDone)));
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperView::DoPaint));
}
void PepperView::SetSolidFill(uint32 color) {
- if (!plugin_->CurrentlyOnPluginThread()) {
- RunTaskOnPluginThread(
- NewRunnableMethod(this, &PepperView::SetSolidFill, color));
- return;
- }
-
- is_static_fill_ = true;
- static_fill_color_ = color;
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperView::DoSetSolidFill, color));
}
void PepperView::UnsetSolidFill() {
- if (!plugin_->CurrentlyOnPluginThread()) {
- RunTaskOnPluginThread(
- NewRunnableMethod(this, &PepperView::UnsetSolidFill));
- return;
- }
-
- is_static_fill_ = false;
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperView::DoUnsetSolidFill));
}
void PepperView::SetViewport(int x, int y, int width, int height) {
- if (!plugin_->CurrentlyOnPluginThread()) {
- RunTaskOnPluginThread(NewRunnableMethod(this, &PepperView::SetViewport,
- x, y, width, height));
- return;
- }
-
- // TODO(ajwong): Should we ignore x & y updates? What do those even mean?
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperView::DoSetViewport,
+ x, y, width, height));
+}
- // TODO(ajwong): What does viewport x, y mean to a plugin anyways?
- viewport_x_ = x;
- viewport_y_ = y;
- viewport_width_ = width;
- viewport_height_ = height;
+void PepperView::SetBackingStoreSize(int width, int height) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperView::DoSetBackingStoreSize,
+ width, height));
+}
- device_context_ =
- pp::DeviceContext2D(viewport_width_, viewport_height_, false);
- if (!plugin_->BindGraphicsDeviceContext(device_context_)) {
- LOG(ERROR) << "Couldn't bind the device context.";
- return;
- }
+void PepperView::HandleBeginUpdateStream(HostMessage* msg) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperView::DoHandleBeginUpdateStream, msg));
}
-void PepperView::SetBackingStoreSize(int width, int height) {
- if (!plugin_->CurrentlyOnPluginThread()) {
- RunTaskOnPluginThread(NewRunnableMethod(this,
- &PepperView::SetBackingStoreSize,
- width, height));
- return;
- }
+void PepperView::HandleUpdateStreamPacket(HostMessage* msg) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperView::DoHandleUpdateStreamPacket, msg));
+}
- backing_store_width_ = width;
- backing_store_height_ = height;
+void PepperView::HandleEndUpdateStream(HostMessage* msg) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperView::DoHandleEndUpdateStream, msg));
}
-void PepperView::HandleBeginUpdateStream(HostMessage* msg) {
- if (!plugin_->CurrentlyOnPluginThread()) {
- RunTaskOnPluginThread(
- NewRunnableMethod(this, &PepperView::HandleBeginUpdateStream,
- msg));
- return;
- }
+void PepperView::DoPaint() {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
- scoped_ptr<HostMessage> deleter(msg);
+ LOG(INFO) << "Starting PepperView::DoPaint";
- // TODO(hclam): Use the information from the message to create the decoder.
- // We lazily construct the decoder.
- if (!decoder_.get()) {
- decoder_.reset(new DecoderVerbatim());
- }
+ NPDeviceContext2D context;
+ NPDeviceContext2DConfig config;
+ rendering_device_->initializeContext(plugin_instance_, &config, &context);
- if (!frame_) {
- media::VideoFrame::CreateFrame(media::VideoFrame::RGB32,
- backing_store_width_,
- backing_store_height_,
- base::TimeDelta(), base::TimeDelta(),
- &frame_);
+ uint32* output_bitmap = static_cast<uint32*>(context.region);
+
+ // TODO(ajwong): Remove debugging code and actually hook up real painting
+ // logic from the decoder.
+ LOG(INFO) << "Painting top: " << context.dirty.top
+ << " bottom: " << context.dirty.bottom
+ << " left: " << context.dirty.left
+ << " right: " << context.dirty.right;
+ for (int i = context.dirty.top; i < context.dirty.bottom; ++i) {
+ for (int j = context.dirty.left; j < context.dirty.right; ++j) {
+ *output_bitmap++ = static_fill_color_;
+ }
}
- // Tell the decoder to do start decoding.
- decoder_->BeginDecode(frame_, &update_rects_,
- NewRunnableMethod(this, &PepperView::OnPartialDecodeDone),
- NewRunnableMethod(this, &PepperView::OnDecodeDone));
+ rendering_device_->flushContext(plugin_instance_, &context, NULL, NULL);
+ LOG(INFO) << "Finishing PepperView::DoPaint";
}
-void PepperView::HandleUpdateStreamPacket(HostMessage* msg) {
- if (!plugin_->CurrentlyOnPluginThread()) {
- RunTaskOnPluginThread(
- NewRunnableMethod(this, &PepperView::HandleUpdateStreamPacket,
- msg));
- return;
- }
+void PepperView::DoSetSolidFill(uint32 color) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
- decoder_->PartialDecode(msg);
+ is_static_fill_ = true;
+ static_fill_color_ = color;
}
-void PepperView::HandleEndUpdateStream(HostMessage* msg) {
- if (!plugin_->CurrentlyOnPluginThread()) {
- RunTaskOnPluginThread(
- NewRunnableMethod(this, &PepperView::HandleEndUpdateStream,
- msg));
- return;
- }
+void PepperView::DoUnsetSolidFill() {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
- scoped_ptr<HostMessage> deleter(msg);
- decoder_->EndDecode();
+ is_static_fill_ = false;
}
-void PepperView::OnPaintDone() {
- // TODO(ajwong):Probably should set some variable to allow repaints to
- // actually paint.
- return;
+void PepperView::DoSetViewport(int x, int y, int width, int height) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+
+ viewport_x_ = x;
+ viewport_y_ = y;
+ viewport_width_ = width;
+ viewport_height_ = height;
+}
+
+void PepperView::DoSetBackingStoreSize(int width, int height) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+
+ backing_store_width_ = width;
+ backing_store_height_ = height;
}
-void PepperView::OnPartialDecodeDone() {
- all_update_rects_.insert(all_update_rects_.begin() +
- all_update_rects_.size(),
- update_rects_.begin(), update_rects_.end());
- Paint();
- // TODO(ajwong): Need to block here to be synchronous.
+void PepperView::DoHandleBeginUpdateStream(HostMessage* msg) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+
+ NOTIMPLEMENTED();
+}
+
+void PepperView::DoHandleUpdateStreamPacket(HostMessage* msg) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+
+ NOTIMPLEMENTED();
}
+void PepperView::DoHandleEndUpdateStream(HostMessage* msg) {
+ DCHECK_EQ(message_loop_, MessageLoop::current());
-void PepperView::OnDecodeDone() {
+ NOTIMPLEMENTED();
}
} // namespace remoting
diff --git a/remoting/client/plugin/pepper_view.h b/remoting/client/plugin/pepper_view.h
index 655b9ae..9dc8a56 100644
--- a/remoting/client/plugin/pepper_view.h
+++ b/remoting/client/plugin/pepper_view.h
@@ -2,38 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// This class is an implementation of the ChromotingView using Pepper devices
-// as the backing stores. The public APIs to this class are thread-safe.
-// Calls will dispatch any interaction with the pepper API onto the pepper
-// main thread.
-//
-// TODO(ajwong): We need to better understand the threading semantics of this
-// class. Currently, we're just going to always run everything on the pepper
-// main thread. Is this smart?
-
#ifndef REMOTING_CLIENT_PLUGIN_PEPPER_VIEW_H_
#define REMOTING_CLIENT_PLUGIN_PEPPER_VIEW_H_
#include "base/scoped_ptr.h"
#include "base/task.h"
-#include "media/base/video_frame.h"
#include "remoting/client/chromoting_view.h"
-#include "remoting/client/decoder.h"
-#include "third_party/ppapi/cpp/device_context_2d.h"
+#include "third_party/npapi/bindings/npapi.h"
+#include "third_party/npapi/bindings/npapi_extensions.h"
+
+class MessageLoop;
namespace remoting {
-class ChromotingPlugin;
class Decoder;
class PepperView : public ChromotingView {
public:
- // Constructs a PepperView that draws to the |rendering_device|. The
+ // Constructs a PepperView that draw to the |rendering_device|. The
// |rendering_device| instance must outlive this class.
//
// TODO(ajwong): This probably needs to synchronize with the pepper thread
// to be safe.
- explicit PepperView(ChromotingPlugin* plugin);
+ PepperView(MessageLoop* message_loop, NPDevice* rendering_device,
+ NPP plugin_instance);
virtual ~PepperView();
// ChromotingView implementation.
@@ -47,16 +39,21 @@ class PepperView : public ChromotingView {
virtual void HandleEndUpdateStream(HostMessage* msg);
private:
- void OnPaintDone();
- void OnPartialDecodeDone();
- void OnDecodeDone();
-
- // Reference to the creating plugin instance. Needed for interacting with
- // pepper. Marking explciitly as const since it must be initialized at
- // object creation, and never change.
- ChromotingPlugin* const plugin_;
-
- pp::DeviceContext2D device_context_;
+ void DoPaint();
+ void DoSetSolidFill(uint32 color);
+ void DoUnsetSolidFill();
+ void DoSetViewport(int x, int y, int width, int height);
+ void DoSetBackingStoreSize(int width, int height);
+ void DoHandleBeginUpdateStream(HostMessage* msg);
+ void DoHandleUpdateStreamPacket(HostMessage* msg);
+ void DoHandleEndUpdateStream(HostMessage* msg);
+
+ // Synchronization and thread handling objects.
+ MessageLoop* message_loop_;
+
+ // Handles to Pepper objects needed for drawing to the screen.
+ NPDevice* rendering_device_;
+ NPP plugin_instance_;
int backing_store_width_;
int backing_store_height_;
@@ -69,10 +66,6 @@ class PepperView : public ChromotingView {
bool is_static_fill_;
uint32 static_fill_color_;
- scoped_refptr<media::VideoFrame> frame_;
- UpdatedRects update_rects_;
- UpdatedRects all_update_rects_;
-
scoped_ptr<Decoder> decoder_;
DISALLOW_COPY_AND_ASSIGN(PepperView);
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index c1450c1..82df802 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -71,8 +71,7 @@
'chromoting_base',
'chromoting_client',
'chromoting_jingle_glue',
- '../third_party/ppapi/ppapi.gyp:ppapi_cpp_objects',
- '../third_party/zlib/zlib.gyp:zlib',
+ '../third_party/ppapi/ppapi.gyp:ppapi_c',
],
'sources': [
'client/plugin/chromoting_plugin.cc',
@@ -81,8 +80,6 @@
'client/plugin/pepper_entrypoints.h',
'client/plugin/pepper_view.cc',
'client/plugin/pepper_view.h',
- 'client/plugin/pepper_util.cc',
- 'client/plugin/pepper_util.h',
'../media/base/yuv_convert.cc',
'../media/base/yuv_convert.h',
'../media/base/yuv_row.h',