Index: remoting/client/x11_view.cc |
diff --git a/remoting/client/x11_view.cc b/remoting/client/x11_view.cc |
index 43ecd656c7e08493494af48113e02780463b0203..9ccdb88e0e4090c9913c8f53af7706269f120d0d 100644 |
--- a/remoting/client/x11_view.cc |
+++ b/remoting/client/x11_view.cc |
@@ -10,7 +10,7 @@ |
#include <X11/extensions/Xcomposite.h> |
#include "base/logging.h" |
-#include "remoting/base/decoder_zlib.h" |
+#include "base/task.h" |
namespace remoting { |
@@ -65,14 +65,15 @@ void X11View::TearDown() { |
} |
void X11View::Paint() { |
+ NOTIMPLEMENTED() << "Not sure if we need this call anymore."; |
+} |
+ |
+void X11View::PaintRect(media::VideoFrame* frame, const gfx::Rect& clip) { |
// Don't bother attempting to paint if the display hasn't been set up. |
- if (!display_ || !window_ || !frame_height_ || !frame_width_ || !frame_) { |
+ if (!display_ || !window_ || !frame) { |
return; |
} |
- // TODO(hclam): Paint only the updated regions. |
- all_update_rects_.clear(); |
- |
// If we have not initialized the render target then do it now. |
if (!picture_) |
InitPaintTarget(); |
@@ -83,8 +84,8 @@ void X11View::Paint() { |
// Creates a XImage. |
XImage image; |
memset(&image, 0, sizeof(image)); |
- image.width = frame_width_; |
- image.height = frame_height_; |
+ image.width = frame->width(); |
+ image.height = frame->height(); |
image.depth = 32; |
image.bits_per_pixel = 32; |
image.format = ZPixmap; |
@@ -100,11 +101,11 @@ void X11View::Paint() { |
// Creates a pixmap and uploads from the XImage. |
unsigned long pixmap = XCreatePixmap(display_, window_, |
- frame_width_, frame_height_, 32); |
+ frame->width(), frame->height(), 32); |
GC gc = XCreateGC(display_, pixmap, 0, NULL); |
- XPutImage(display_, pixmap, gc, &image, 0, 0, 0, 0, |
- frame_width_, frame_height_); |
+ XPutImage(display_, pixmap, gc, &image, clip.x(), clip.y(), |
+ clip.x(), clip.y(), clip.width(), clip.height()); |
XFreeGC(display_, gc); |
// Creates the picture representing the pixmap. |
@@ -115,8 +116,8 @@ void X11View::Paint() { |
// Composite the picture over the picture representing the window. |
XRenderComposite(display_, PictOpSrc, picture, 0, |
- picture_, 0, 0, 0, 0, 0, 0, |
- frame_width_, frame_height_); |
+ picture_, 0, 0, 0, 0, clip.x(), clip.y(), |
+ clip.width(), clip.height()); |
XRenderFreePicture(display_, picture); |
XFreePixmap(display_, pixmap); |
@@ -137,14 +138,6 @@ void X11View::SetViewport(int x, int y, int width, int height) { |
// NOTIMPLEMENTED(); |
} |
-void X11View::SetHostScreenSize(int width, int height) { |
- frame_width_ = width; |
- frame_height_ = height; |
- frame_ = NULL; |
- |
- XResizeWindow(display_, window_, frame_width_, frame_height_); |
-} |
- |
void X11View::InitPaintTarget() { |
// Testing XRender support. |
int dummy; |
@@ -163,60 +156,52 @@ void X11View::InitPaintTarget() { |
CHECK(picture_) << "Backing picture not created"; |
} |
-void X11View::HandleBeginUpdateStream(ChromotingHostMessage* msg) { |
- 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 X11View::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 use the native X window rather than |
+ // just a generic frame buffer. |
+ 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 X11View::HandleUpdateStreamPacket(ChromotingHostMessage* msg) { |
- // Lazily initialize the decoder. |
- SetupDecoder(msg->update_stream_packet().begin_rect().encoding()); |
- if (!decoder_->IsStarted()) { |
- BeginDecoding(NewRunnableMethod(this, &X11View::OnPartialDecodeDone), |
- NewRunnableMethod(this, &X11View::OnDecodeDone)); |
+void X11View::ReleaseFrame(media::VideoFrame* frame) { |
+ if (frame) { |
+ LOG(WARNING) << "Frame released."; |
+ frame->Release(); |
} |
- |
- Decode(msg); |
} |
-void X11View::HandleEndUpdateStream(ChromotingHostMessage* msg) { |
- scoped_ptr<ChromotingHostMessage> deleter(msg); |
- EndDecoding(); |
-} |
- |
-void X11View::OnPartialDecodeDone() { |
- // Decoder has produced some output so schedule a paint. We'll get a Paint() |
- // call in the near future. Note that we can get UpdateStreamPacket during |
- // this short period of time and we will perform decode again and the |
- // information in updated rects will be lost. |
- // There are several ways to solve this problem. |
- // 1. Merge the updated rects and perform one paint. |
- // 2. Queue the updated rects and perform two paints. |
- // 3. Ignore the updated rects and always paint the full image. Since we |
- // use one frame as output this will always be correct. |
- // We will take (1) and simply concat the list of rectangles. |
- all_update_rects_.insert(all_update_rects_.begin() + |
- all_update_rects_.size(), |
- update_rects_.begin(), update_rects_.end()); |
- |
+void X11View::OnPartialFrameOutput(media::VideoFrame* frame, |
+ UpdatedRects* rects, |
+ Task* done) { |
// TODO(hclam): Make sure we call this method on the right thread. Since |
// decoder is single-threaded we don't have a problem but we better post |
// a task to do the right thing. |
+ |
+ for (UpdatedRects::iterator it = rects->begin(); it != rects->end(); ++it) { |
+ PaintRect(frame, *it); |
+ } |
+ |
+ // TODO(ajwong): Shouldn't we only expose the part of the window that was |
+ // damanged? |
XEvent event; |
event.type = Expose; |
XSendEvent(display_, static_cast<int>(window_), true, ExposureMask, &event); |
-} |
-void X11View::OnDecodeDone() { |
- // Since we do synchronous decoding here there's nothing in this method. |
+ done->Run(); |
+ delete done; |
} |
} // namespace remoting |