Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Unified Diff: remoting/client/rectangle_update_decoder.cc

Issue 9331003: Improving the decoder pipeline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/client/rectangle_update_decoder.cc
diff --git a/remoting/client/rectangle_update_decoder.cc b/remoting/client/rectangle_update_decoder.cc
index 673c2a037061f78d23afbd4c916b6c5995e750a7..14f768ff85462317136f992cd8a0014e36763508 100644
--- a/remoting/client/rectangle_update_decoder.cc
+++ b/remoting/client/rectangle_update_decoder.cc
@@ -10,6 +10,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
+#include "ppapi/cpp/image_data.h"
#include "remoting/base/decoder.h"
#include "remoting/base/decoder_row_based.h"
#include "remoting/base/decoder_vp8.h"
@@ -27,8 +28,9 @@ RectangleUpdateDecoder::RectangleUpdateDecoder(
: message_loop_(message_loop),
consumer_(consumer),
screen_size_(SkISize::Make(0, 0)),
- clip_rect_(SkIRect::MakeEmpty()),
- decoder_needs_reset_(false) {
+ update_pending_(false),
+ view_size_(SkISize::Make(0, 0)),
+ clip_area_(SkIRect::MakeEmpty()) {
}
RectangleUpdateDecoder::~RectangleUpdateDecoder() {
@@ -56,24 +58,19 @@ void RectangleUpdateDecoder::DecodePacket(const VideoPacket* packet,
this, packet, done));
return;
}
- AllocateFrame(packet, done);
-}
-void RectangleUpdateDecoder::AllocateFrame(const VideoPacket* packet,
- const base::Closure& done) {
- if (!message_loop_->BelongsToCurrentThread()) {
- message_loop_->PostTask(
- FROM_HERE, base::Bind(&RectangleUpdateDecoder::AllocateFrame,
- this, packet, done));
- return;
- }
base::ScopedClosureRunner done_runner(done);
+ bool decoder_needs_reset = false;
// If the packet includes a screen size, store it.
if (packet->format().has_screen_width() &&
packet->format().has_screen_height()) {
- screen_size_.set(packet->format().screen_width(),
- packet->format().screen_height());
+ SkISize screen_size = SkISize::Make(packet->format().screen_width(),
+ packet->format().screen_height());
+ if (screen_size_ != screen_size) {
+ screen_size_ = screen_size;
+ decoder_needs_reset = true;
Wez 2012/02/07 01:56:31 So we really need to reset the decoder on host res
alexeypa (please no reviews) 2012/02/15 23:06:22 I don't know but I'd like to avoid adding more cha
+ }
}
// If we've never seen a screen size, ignore the packet.
@@ -81,42 +78,9 @@ void RectangleUpdateDecoder::AllocateFrame(const VideoPacket* packet,
return;
}
- // Ensure the output frame is the right size.
- SkISize frame_size = SkISize::Make(0, 0);
- if (frame_)
- frame_size.set(frame_->width(), frame_->height());
-
- // Allocate a new frame, if necessary.
- if ((!frame_) || (screen_size_ != frame_size)) {
- if (frame_) {
- consumer_->ReleaseFrame(frame_);
- frame_ = NULL;
- }
-
- consumer_->AllocateFrame(
- media::VideoFrame::RGB32, screen_size_, &frame_,
- base::Bind(&RectangleUpdateDecoder::ProcessPacketData,
- this, packet, done_runner.Release()));
- decoder_needs_reset_ = true;
- return;
- }
- ProcessPacketData(packet, done_runner.Release());
-}
-
-void RectangleUpdateDecoder::ProcessPacketData(
- const VideoPacket* packet, const base::Closure& done) {
- if (!message_loop_->BelongsToCurrentThread()) {
- message_loop_->PostTask(
- FROM_HERE, base::Bind(&RectangleUpdateDecoder::ProcessPacketData,
- this, packet, done));
- return;
- }
- base::ScopedClosureRunner done_runner(done);
-
- if (decoder_needs_reset_) {
+ if (decoder_needs_reset) {
decoder_->Reset();
- decoder_->Initialize(frame_);
- decoder_needs_reset_ = false;
+ decoder_->Initialize(screen_size_);
}
if (!decoder_->IsReadyForData()) {
@@ -129,106 +93,59 @@ void RectangleUpdateDecoder::ProcessPacketData(
SubmitToConsumer();
}
-void RectangleUpdateDecoder::SetOutputSize(const SkISize& size) {
+void RectangleUpdateDecoder::RefreshFullFrame() {
if (!message_loop_->BelongsToCurrentThread()) {
message_loop_->PostTask(
- FROM_HERE, base::Bind(&RectangleUpdateDecoder::SetOutputSize,
- this, size));
+ FROM_HERE, base::Bind(&RectangleUpdateDecoder::RefreshFullFrame, this));
return;
}
- // TODO(wez): Refresh the frame only if the ratio has changed.
- if (frame_) {
- SkIRect frame_rect = SkIRect::MakeWH(frame_->width(), frame_->height());
- refresh_region_.op(frame_rect, SkRegion::kUnion_Op);
- }
-
- // TODO(hclam): If the scale ratio has changed we should reallocate a
- // VideoFrame of different size. However if the scale ratio is always
- // smaller than 1.0 we can use the same video frame.
if (decoder_.get()) {
- decoder_->SetOutputSize(size);
- RefreshFullFrame();
+ SkRegion region;
+ region.op(SkIRect::MakeSize(screen_size_), SkRegion::kUnion_Op);
+ decoder_->UpdateRegion(region);
+ SubmitToConsumer();
}
}
-void RectangleUpdateDecoder::UpdateClipRect(const SkIRect& new_clip_rect) {
- if (!message_loop_->BelongsToCurrentThread()) {
- message_loop_->PostTask(
- FROM_HERE, base::Bind(&RectangleUpdateDecoder::UpdateClipRect,
- this, new_clip_rect));
- return;
- }
-
- if (new_clip_rect == clip_rect_ || !decoder_.get())
- return;
+void RectangleUpdateDecoder::SubmitToConsumer() {
+ DCHECK(message_loop_->BelongsToCurrentThread());
- // TODO(wez): Only refresh newly-exposed portions of the frame.
- if (frame_) {
- SkIRect frame_rect = SkIRect::MakeWH(frame_->width(), frame_->height());
- refresh_region_.op(frame_rect, SkRegion::kUnion_Op);
+ if (!update_pending_) {
+ // Make sure OnFrameReady() will not be called again until OnPaintFrame()
+ // is invoked.
+ update_pending_ = true;
+ consumer_->OnFrameReady(
+ screen_size_,
+ &view_size_, &clip_area_, &backing_store_,
+ base::Bind(&RectangleUpdateDecoder::OnPaintFrame, this));
}
-
- clip_rect_ = new_clip_rect;
- decoder_->SetClipRect(new_clip_rect);
-
- // TODO(wez): Defer refresh so that multiple events can be batched.
- DoRefresh();
}
-void RectangleUpdateDecoder::RefreshFullFrame() {
+void RectangleUpdateDecoder::OnPaintFrame() {
if (!message_loop_->BelongsToCurrentThread()) {
message_loop_->PostTask(
- FROM_HERE, base::Bind(&RectangleUpdateDecoder::RefreshFullFrame, this));
+ FROM_HERE, base::Bind(&RectangleUpdateDecoder::OnPaintFrame,
+ this));
return;
}
- // If a video frame or the decoder is not allocated yet then don't
- // save the refresh rectangle to avoid wasted computation.
- if (!frame_ || !decoder_.get())
- return;
-
- SkIRect frame_rect = SkIRect::MakeWH(frame_->width(), frame_->height());
- refresh_region_.op(frame_rect, SkRegion::kUnion_Op);
-
- DoRefresh();
-}
-
-void RectangleUpdateDecoder::SubmitToConsumer() {
- // A frame is not allocated yet, we can reach here because of a refresh
- // request.
- if (!frame_)
- return;
+ update_pending_ = false;
- SkRegion* dirty_region = new SkRegion;
- decoder_->GetUpdatedRegion(dirty_region);
+ // Skip painting if the backing store is not ready yet.
+ if (backing_store_.get() && !backing_store_->is_null()) {
+ // Draw the updated region to the backing store.
+ scoped_ptr<SkRegion> output_region(new SkRegion());
+ decoder_->Draw(view_size_, clip_area_,
+ reinterpret_cast<uint8*>(backing_store_->data()),
+ backing_store_->stride(),
+ output_region.get());
- consumer_->OnPartialFrameOutput(frame_, dirty_region, base::Bind(
- &RectangleUpdateDecoder::OnFrameConsumed, this, dirty_region));
-}
-
-void RectangleUpdateDecoder::DoRefresh() {
- DCHECK(message_loop_->BelongsToCurrentThread());
-
- if (refresh_region_.isEmpty())
- return;
-
- decoder_->RefreshRegion(refresh_region_);
- refresh_region_.setEmpty();
- SubmitToConsumer();
-}
-
-void RectangleUpdateDecoder::OnFrameConsumed(SkRegion* region) {
- if (!message_loop_->BelongsToCurrentThread()) {
- message_loop_->PostTask(
- FROM_HERE, base::Bind(&RectangleUpdateDecoder::OnFrameConsumed,
- this, region));
- return;
+ // Notify the consumer that painting is done.
+ consumer_->OnPaintDone(backing_store_.Pass(), output_region.Pass());
+ } else {
+ LOG(ERROR) << "Backing store is not available.";
}
-
- delete region;
-
- DoRefresh();
}
} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698