summaryrefslogtreecommitdiffstats
path: root/remoting/client/plugin/pepper_view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/client/plugin/pepper_view.cc')
-rw-r--r--remoting/client/plugin/pepper_view.cc234
1 files changed, 142 insertions, 92 deletions
diff --git a/remoting/client/plugin/pepper_view.cc b/remoting/client/plugin/pepper_view.cc
index d66624b5..a6ebc13 100644
--- a/remoting/client/plugin/pepper_view.cc
+++ b/remoting/client/plugin/pepper_view.cc
@@ -6,14 +6,17 @@
#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"
+#include "third_party/ppapi/cpp/point.h"
+#include "third_party/ppapi/cpp/size.h"
namespace remoting {
-PepperView::PepperView(MessageLoop* message_loop, NPDevice* rendering_device,
- NPP plugin_instance)
- : message_loop_(message_loop),
- rendering_device_(rendering_device),
- plugin_instance_(plugin_instance),
+PepperView::PepperView(ChromotingPlugin* plugin)
+ : plugin_(plugin),
backing_store_width_(0),
backing_store_height_(0),
viewport_x_(0),
@@ -28,127 +31,174 @@ PepperView::~PepperView() {
}
void PepperView::Paint() {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PepperView::DoPaint));
-}
-
-void PepperView::SetSolidFill(uint32 color) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PepperView::DoSetSolidFill, color));
-}
-
-void PepperView::UnsetSolidFill() {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PepperView::DoUnsetSolidFill));
-}
-
-void PepperView::SetViewport(int x, int y, int width, int height) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PepperView::DoSetViewport,
- x, y, width, height));
-}
-
-void PepperView::SetBackingStoreSize(int width, int height) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PepperView::DoSetBackingStoreSize,
- width, height));
-}
-
-void PepperView::HandleBeginUpdateStream(HostMessage* msg) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PepperView::DoHandleBeginUpdateStream, msg));
-}
-
-void PepperView::HandleUpdateStreamPacket(HostMessage* msg) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PepperView::DoHandleUpdateStreamPacket, msg));
-}
-
-void PepperView::HandleEndUpdateStream(HostMessage* msg) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PepperView::DoHandleEndUpdateStream, msg));
-}
-
-void PepperView::DoPaint() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
-
- LOG(INFO) << "Starting PepperView::DoPaint";
-
- NPDeviceContext2D context;
- NPDeviceContext2DConfig config;
- rendering_device_->initializeContext(plugin_instance_, &config, &context);
+ if (!plugin_->CurrentlyOnPluginThread()) {
+ RunTaskOnPluginThread(NewRunnableMethod(this, &PepperView::Paint));
+ return;
+ }
- uint32* output_bitmap = static_cast<uint32*>(context.region);
+ // TODO(ajwong): We shouldn't assume the image data format.
+ pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(viewport_width_, viewport_height_),
+ false);
+ if (image.is_null()) {
+ LOG(ERROR) << "Unable to allocate image.";
+ return;
+ }
- // 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_;
+ if (is_static_fill_) {
+ for (int y = 0; y < image.size().height(); y++) {
+ for (int x = 0; x < image.size().width(); x++) {
+ *image.GetAddr32(pp::Point(x, y)) = static_fill_color_;
+ }
+ }
+ } else if (frame_) {
+ uint32_t* frame_data =
+ reinterpret_cast<uint32_t*>(frame_->data(media::VideoFrame::kRGBPlane));
+ int max_height = std::min(backing_store_height_, image.size().height());
+ int max_width = std::min(backing_store_width_, image.size().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(pp::Point(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;
}
-
- rendering_device_->flushContext(plugin_instance_, &context, NULL, NULL);
- LOG(INFO) << "Finishing PepperView::DoPaint";
+ device_context_.ReplaceContents(&image);
+ device_context_.Flush(TaskToCompletionCallback(
+ NewRunnableMethod(this, &PepperView::OnPaintDone)));
}
-void PepperView::DoSetSolidFill(uint32 color) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+void PepperView::SetSolidFill(uint32 color) {
+ if (!plugin_->CurrentlyOnPluginThread()) {
+ RunTaskOnPluginThread(
+ NewRunnableMethod(this, &PepperView::SetSolidFill, color));
+ return;
+ }
is_static_fill_ = true;
static_fill_color_ = color;
}
-void PepperView::DoUnsetSolidFill() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+void PepperView::UnsetSolidFill() {
+ if (!plugin_->CurrentlyOnPluginThread()) {
+ RunTaskOnPluginThread(
+ NewRunnableMethod(this, &PepperView::UnsetSolidFill));
+ return;
+ }
is_static_fill_ = false;
}
-void PepperView::DoSetViewport(int x, int y, int width, int height) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+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?
+
+ // TODO(ajwong): What does viewport x, y mean to a plugin anyways?
viewport_x_ = x;
viewport_y_ = y;
viewport_width_ = width;
viewport_height_ = height;
+
+ device_context_ =
+ pp::DeviceContext2D(pp::Size(viewport_width_, viewport_height_), false);
+ if (!plugin_->BindGraphicsDeviceContext(device_context_)) {
+ LOG(ERROR) << "Couldn't bind the device context.";
+ return;
+ }
}
-void PepperView::DoSetBackingStoreSize(int width, int height) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+void PepperView::SetBackingStoreSize(int width, int height) {
+ if (!plugin_->CurrentlyOnPluginThread()) {
+ RunTaskOnPluginThread(NewRunnableMethod(this,
+ &PepperView::SetBackingStoreSize,
+ width, height));
+ return;
+ }
backing_store_width_ = width;
backing_store_height_ = height;
}
-void PepperView::DoHandleBeginUpdateStream(HostMessage* msg) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+void PepperView::HandleBeginUpdateStream(HostMessage* msg) {
+ if (!plugin_->CurrentlyOnPluginThread()) {
+ RunTaskOnPluginThread(
+ NewRunnableMethod(this, &PepperView::HandleBeginUpdateStream,
+ msg));
+ return;
+ }
+
+ scoped_ptr<HostMessage> deleter(msg);
- NOTIMPLEMENTED();
+ // TODO(hclam): Use the information from the message to create the decoder.
+ // We lazily construct the decoder.
+ if (!decoder_.get()) {
+ decoder_.reset(new DecoderVerbatim());
+ }
+
+ if (!frame_) {
+ media::VideoFrame::CreateFrame(media::VideoFrame::RGB32,
+ backing_store_width_,
+ backing_store_height_,
+ base::TimeDelta(), base::TimeDelta(),
+ &frame_);
+ }
+
+ // Tell the decoder to do start decoding.
+ decoder_->BeginDecode(frame_, &update_rects_,
+ NewRunnableMethod(this, &PepperView::OnPartialDecodeDone),
+ NewRunnableMethod(this, &PepperView::OnDecodeDone));
+}
+
+void PepperView::HandleUpdateStreamPacket(HostMessage* msg) {
+ if (!plugin_->CurrentlyOnPluginThread()) {
+ RunTaskOnPluginThread(
+ NewRunnableMethod(this, &PepperView::HandleUpdateStreamPacket,
+ msg));
+ return;
+ }
+
+ decoder_->PartialDecode(msg);
}
-void PepperView::DoHandleUpdateStreamPacket(HostMessage* msg) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+void PepperView::HandleEndUpdateStream(HostMessage* msg) {
+ if (!plugin_->CurrentlyOnPluginThread()) {
+ RunTaskOnPluginThread(
+ NewRunnableMethod(this, &PepperView::HandleEndUpdateStream,
+ msg));
+ return;
+ }
+
+ scoped_ptr<HostMessage> deleter(msg);
+ decoder_->EndDecode();
+}
+
+void PepperView::OnPaintDone() {
+ // TODO(ajwong):Probably should set some variable to allow repaints to
+ // actually paint.
+ return;
+}
- NOTIMPLEMENTED();
+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::DoHandleEndUpdateStream(HostMessage* msg) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
- NOTIMPLEMENTED();
+void PepperView::OnDecodeDone() {
}
} // namespace remoting