Index: remoting/client/plugin/pepper_view.cc |
diff --git a/remoting/client/plugin/pepper_view.cc b/remoting/client/plugin/pepper_view.cc |
index cc72c43fe7c9e48a99597f725001f4256bb1dadb..eacb37d4ef5f253f93e8a4911fc4d36c69d370a8 100644 |
--- a/remoting/client/plugin/pepper_view.cc |
+++ b/remoting/client/plugin/pepper_view.cc |
@@ -5,6 +5,8 @@ |
#include "remoting/client/plugin/pepper_view.h" |
#include "base/message_loop.h" |
+#include "remoting/base/tracer.h" |
+#include "remoting/client/client_context.h" |
#include "remoting/client/plugin/chromoting_instance.h" |
#include "remoting/client/plugin/pepper_util.h" |
#include "third_party/ppapi/cpp/graphics_2d.h" |
@@ -14,14 +16,15 @@ |
namespace remoting { |
-PepperView::PepperView(ChromotingInstance* instance) |
- : instance_(instance), |
- viewport_x_(0), |
- viewport_y_(0), |
- viewport_width_(0), |
- viewport_height_(0), |
- is_static_fill_(false), |
- static_fill_color_(0) { |
+PepperView::PepperView(ChromotingInstance* instance, ClientContext* context) |
+ : instance_(instance), |
+ context_(context), |
+ viewport_x_(0), |
+ viewport_y_(0), |
+ viewport_width_(0), |
+ viewport_height_(0), |
+ is_static_fill_(false), |
+ static_fill_color_(0) { |
} |
PepperView::~PepperView() { |
@@ -36,10 +39,47 @@ void PepperView::TearDown() { |
void PepperView::Paint() { |
if (!instance_->CurrentlyOnPluginThread()) { |
- RunTaskOnPluginThread(NewRunnableMethod(this, &PepperView::Paint)); |
+ RunTaskOnPluginThread(NewTracedMethod(this, &PepperView::Paint)); |
return; |
} |
+ TraceContext::tracer()->PrintString("Start Paint."); |
+ // TODO(ajwong): We're assuming the native format is BGRA_PREMUL below. This |
+ // is wrong. |
+ if (is_static_fill_) { |
+ LOG(ERROR) << "Static filling " << static_fill_color_; |
+ pp::ImageData image(pp::ImageData::GetNativeImageDataFormat(), |
+ pp::Size(viewport_width_, viewport_height_), |
+ false); |
+ if (image.is_null()) { |
+ LOG(ERROR) << "Unable to allocate image of size: " |
+ << viewport_width_ << "x" << viewport_height_; |
+ return; |
+ } |
+ |
+ 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_; |
+ } |
+ } |
+ |
+ // For ReplaceContents, make sure the image size matches the device context |
+ // size! Otherwise, this will just silently do nothing. |
+ graphics2d_.ReplaceContents(&image); |
+ graphics2d_.Flush(TaskToCompletionCallback( |
+ NewTracedMethod(this, &PepperView::OnPaintDone))); |
+ } else { |
+ // TODO(ajwong): We need to keep a backing store image of the viewport that |
+ // has the data here which can be redrawn. |
+ return; |
+ } |
+ TraceContext::tracer()->PrintString("End Paint."); |
+} |
+ |
+void PepperView::PaintFrame(media::VideoFrame* frame, UpdatedRects* rects) { |
+ DCHECK(instance_->CurrentlyOnPluginThread()); |
+ |
+ TraceContext::tracer()->PrintString("Start Paint Frame."); |
// TODO(ajwong): We're assuming the native format is BGRA_PREMUL below. This |
// is wrong. |
pp::ImageData image(pp::ImageData::GetNativeImageDataFormat(), |
@@ -47,43 +87,37 @@ void PepperView::Paint() { |
false); |
if (image.is_null()) { |
LOG(ERROR) << "Unable to allocate image of size: " |
- << viewport_width_ << "x" << viewport_height_; |
+ << frame->width() << "x" << frame->height(); |
return; |
} |
- 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(frame_height_, image.size().height()); |
- int max_width = std::min(frame_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*frame_width_ + x] | 0xFF000000; |
- } |
+ uint32_t* frame_data = |
+ reinterpret_cast<uint32_t*>(frame->data(media::VideoFrame::kRGBPlane)); |
+ int frame_width = static_cast<int>(frame->width()); |
+ int frame_height = static_cast<int>(frame->height()); |
+ int max_height = std::min(frame_height, image.size().height()); |
+ int max_width = std::min(frame_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*frame_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))); |
+ |
+ // For ReplaceContents, make sure the image size matches the device context |
+ // size! Otherwise, this will just silently do nothing. |
+ graphics2d_.ReplaceContents(&image); |
+ graphics2d_.Flush(TaskToCompletionCallback( |
+ NewTracedMethod(this, &PepperView::OnPaintDone))); |
+ |
+ TraceContext::tracer()->PrintString("End Paint Frame."); |
} |
void PepperView::SetSolidFill(uint32 color) { |
if (!instance_->CurrentlyOnPluginThread()) { |
RunTaskOnPluginThread( |
- NewRunnableMethod(this, &PepperView::SetSolidFill, color)); |
+ NewTracedMethod(this, &PepperView::SetSolidFill, color)); |
return; |
} |
@@ -94,7 +128,7 @@ void PepperView::SetSolidFill(uint32 color) { |
void PepperView::UnsetSolidFill() { |
if (!instance_->CurrentlyOnPluginThread()) { |
RunTaskOnPluginThread( |
- NewRunnableMethod(this, &PepperView::UnsetSolidFill)); |
+ NewTracedMethod(this, &PepperView::UnsetSolidFill)); |
return; |
} |
@@ -103,7 +137,7 @@ void PepperView::UnsetSolidFill() { |
void PepperView::SetViewport(int x, int y, int width, int height) { |
if (!instance_->CurrentlyOnPluginThread()) { |
- RunTaskOnPluginThread(NewRunnableMethod(this, &PepperView::SetViewport, |
+ RunTaskOnPluginThread(NewTracedMethod(this, &PepperView::SetViewport, |
x, y, width, height)); |
return; |
} |
@@ -116,95 +150,64 @@ void PepperView::SetViewport(int x, int y, int width, int height) { |
viewport_width_ = width; |
viewport_height_ = height; |
- device_context_ = |
- pp::Graphics2D(pp::Size(viewport_width_, viewport_height_), false); |
- if (!instance_->BindGraphics(device_context_)) { |
+ graphics2d_ = pp::Graphics2D(pp::Size(viewport_width_, viewport_height_), |
+ false); |
+ if (!instance_->BindGraphics(graphics2d_)) { |
LOG(ERROR) << "Couldn't bind the device context."; |
return; |
} |
} |
-void PepperView::SetHostScreenSize(int width, int height) { |
- if (!instance_->CurrentlyOnPluginThread()) { |
- RunTaskOnPluginThread(NewRunnableMethod(this, |
- &PepperView::SetHostScreenSize, |
- width, height)); |
- return; |
- } |
- |
- frame_width_ = width; |
- frame_height_ = height; |
- |
- // Reset |frame_| - it will be recreated by the next update stream. |
- frame_ = NULL; |
-} |
- |
-void PepperView::HandleBeginUpdateStream(ChromotingHostMessage* msg) { |
- if (!instance_->CurrentlyOnPluginThread()) { |
- RunTaskOnPluginThread( |
- NewRunnableMethod(this, &PepperView::HandleBeginUpdateStream, |
- msg)); |
- return; |
- } |
- |
- scoped_ptr<ChromotingHostMessage> deleter(msg); |
- |
- // Make sure the |frame_| is initialized. |
- if (!frame_) { |
- media::VideoFrame::CreateFrame(media::VideoFrame::RGB32, |
- frame_width_, frame_height_, |
- base::TimeDelta(), base::TimeDelta(), |
- &frame_); |
- CHECK(frame_); |
+void PepperView::AllocateFrame(media::VideoFrame::Format format, |
+ size_t width, |
+ size_t height, |
+ base::TimeDelta timestamp, |
+ base::TimeDelta duration, |
+ scoped_refptr<media::VideoFrame>* frame_out, |
+ Task* done) { |
+ // TODO(ajwong): Implement this to be backed by an pp::ImageData rather than |
+ // generic memory. |
+ media::VideoFrame::CreateFrame(media::VideoFrame::RGB32, |
+ width, height, |
+ base::TimeDelta(), base::TimeDelta(), |
+ frame_out); |
+ if (*frame_out) { |
+ (*frame_out)->AddRef(); |
} |
+ done->Run(); |
+ delete done; |
} |
-void PepperView::HandleUpdateStreamPacket(ChromotingHostMessage* msg) { |
- if (!instance_->CurrentlyOnPluginThread()) { |
- RunTaskOnPluginThread( |
- NewRunnableMethod(this, &PepperView::HandleUpdateStreamPacket, |
- msg)); |
- return; |
+void PepperView::ReleaseFrame(media::VideoFrame* frame) { |
+ if (frame) { |
+ LOG(WARNING) << "Frame released."; |
+ frame->Release(); |
} |
- |
- // Lazily initialize the decoder. |
- SetupDecoder(msg->update_stream_packet().begin_rect().encoding()); |
- if (!decoder_->IsStarted()) { |
- BeginDecoding(NewRunnableMethod(this, &PepperView::OnPartialDecodeDone), |
- NewRunnableMethod(this, &PepperView::OnDecodeDone)); |
- } |
- |
- Decode(msg); |
} |
-void PepperView::HandleEndUpdateStream(ChromotingHostMessage* msg) { |
+void PepperView::OnPartialFrameOutput(media::VideoFrame* frame, |
+ UpdatedRects* rects, |
+ Task* done) { |
if (!instance_->CurrentlyOnPluginThread()) { |
- RunTaskOnPluginThread( |
- NewRunnableMethod(this, &PepperView::HandleEndUpdateStream, |
- msg)); |
+ RunTaskOnPluginThread(NewTracedMethod(this, |
+ &PepperView::OnPartialFrameOutput, |
+ frame, rects, done)); |
return; |
} |
- scoped_ptr<ChromotingHostMessage> deleter(msg); |
- EndDecoding(); |
+ TraceContext::tracer()->PrintString("Calling PaintFrame"); |
+ // TODO(ajwong): Clean up this API to be async so we don't need to use a |
+ // member variable as a hack. |
+ PaintFrame(frame, rects); |
+ done->Run(); |
+ delete done; |
} |
void PepperView::OnPaintDone() { |
// TODO(ajwong):Probably should set some variable to allow repaints to |
// actually paint. |
+ TraceContext::tracer()->PrintString("Paint flushed"); |
return; |
} |
-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::OnDecodeDone() { |
-} |
- |
} // namespace remoting |