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

Side by Side Diff: remoting/client/x11_view.cc

Issue 3305001: Move decoder into separate thread, clean up API layering, and redo update protocl (Closed)
Patch Set: Fix compile error. Created 10 years, 2 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 unified diff | Download patch
« no previous file with comments | « remoting/client/x11_view.h ('k') | remoting/host/capturer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/client/x11_view.h" 5 #include "remoting/client/x11_view.h"
6 6
7 #include <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 #include <X11/Xutil.h> 8 #include <X11/Xutil.h>
9 #include <X11/extensions/Xrender.h> 9 #include <X11/extensions/Xrender.h>
10 #include <X11/extensions/Xcomposite.h> 10 #include <X11/extensions/Xcomposite.h>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "remoting/base/decoder_zlib.h" 13 #include "base/task.h"
14 14
15 namespace remoting { 15 namespace remoting {
16 16
17 X11View::X11View() 17 X11View::X11View()
18 : display_(NULL), 18 : display_(NULL),
19 window_(0), 19 window_(0),
20 picture_(0) { 20 picture_(0) {
21 } 21 }
22 22
23 X11View::~X11View() { 23 X11View::~X11View() {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 if (display_ && window_) { 58 if (display_ && window_) {
59 // Shutdown the window system. 59 // Shutdown the window system.
60 XDestroyWindow(display_, window_); 60 XDestroyWindow(display_, window_);
61 XCloseDisplay(display_); 61 XCloseDisplay(display_);
62 } 62 }
63 display_ = NULL; 63 display_ = NULL;
64 window_ = 0; 64 window_ = 0;
65 } 65 }
66 66
67 void X11View::Paint() { 67 void X11View::Paint() {
68 NOTIMPLEMENTED() << "Not sure if we need this call anymore.";
69 }
70
71 void X11View::PaintRect(media::VideoFrame* frame, const gfx::Rect& clip) {
68 // Don't bother attempting to paint if the display hasn't been set up. 72 // Don't bother attempting to paint if the display hasn't been set up.
69 if (!display_ || !window_ || !frame_height_ || !frame_width_ || !frame_) { 73 if (!display_ || !window_ || !frame) {
70 return; 74 return;
71 } 75 }
72 76
73 // TODO(hclam): Paint only the updated regions.
74 all_update_rects_.clear();
75
76 // If we have not initialized the render target then do it now. 77 // If we have not initialized the render target then do it now.
77 if (!picture_) 78 if (!picture_)
78 InitPaintTarget(); 79 InitPaintTarget();
79 80
80 // Upload the image to a pixmap. And then create a picture from the pixmap 81 // Upload the image to a pixmap. And then create a picture from the pixmap
81 // and composite the picture over the picture representing the window. 82 // and composite the picture over the picture representing the window.
82 83
83 // Creates a XImage. 84 // Creates a XImage.
84 XImage image; 85 XImage image;
85 memset(&image, 0, sizeof(image)); 86 memset(&image, 0, sizeof(image));
86 image.width = frame_width_; 87 image.width = frame->width();
87 image.height = frame_height_; 88 image.height = frame->height();
88 image.depth = 32; 89 image.depth = 32;
89 image.bits_per_pixel = 32; 90 image.bits_per_pixel = 32;
90 image.format = ZPixmap; 91 image.format = ZPixmap;
91 image.byte_order = LSBFirst; 92 image.byte_order = LSBFirst;
92 image.bitmap_unit = 8; 93 image.bitmap_unit = 8;
93 image.bitmap_bit_order = LSBFirst; 94 image.bitmap_bit_order = LSBFirst;
94 image.bytes_per_line = frame_->stride(media::VideoFrame::kRGBPlane); 95 image.bytes_per_line = frame_->stride(media::VideoFrame::kRGBPlane);
95 image.red_mask = 0xff; 96 image.red_mask = 0xff;
96 image.green_mask = 0xff00; 97 image.green_mask = 0xff00;
97 image.blue_mask = 0xff0000; 98 image.blue_mask = 0xff0000;
98 image.data = reinterpret_cast<char*>( 99 image.data = reinterpret_cast<char*>(
99 frame_->data(media::VideoFrame::kRGBPlane)); 100 frame_->data(media::VideoFrame::kRGBPlane));
100 101
101 // Creates a pixmap and uploads from the XImage. 102 // Creates a pixmap and uploads from the XImage.
102 unsigned long pixmap = XCreatePixmap(display_, window_, 103 unsigned long pixmap = XCreatePixmap(display_, window_,
103 frame_width_, frame_height_, 32); 104 frame->width(), frame->height(), 32);
104 105
105 GC gc = XCreateGC(display_, pixmap, 0, NULL); 106 GC gc = XCreateGC(display_, pixmap, 0, NULL);
106 XPutImage(display_, pixmap, gc, &image, 0, 0, 0, 0, 107 XPutImage(display_, pixmap, gc, &image, clip.x(), clip.y(),
107 frame_width_, frame_height_); 108 clip.x(), clip.y(), clip.width(), clip.height());
108 XFreeGC(display_, gc); 109 XFreeGC(display_, gc);
109 110
110 // Creates the picture representing the pixmap. 111 // Creates the picture representing the pixmap.
111 XID picture = XRenderCreatePicture( 112 XID picture = XRenderCreatePicture(
112 display_, pixmap, 113 display_, pixmap,
113 XRenderFindStandardFormat(display_, PictStandardARGB32), 114 XRenderFindStandardFormat(display_, PictStandardARGB32),
114 0, NULL); 115 0, NULL);
115 116
116 // Composite the picture over the picture representing the window. 117 // Composite the picture over the picture representing the window.
117 XRenderComposite(display_, PictOpSrc, picture, 0, 118 XRenderComposite(display_, PictOpSrc, picture, 0,
118 picture_, 0, 0, 0, 0, 0, 0, 119 picture_, 0, 0, 0, 0, clip.x(), clip.y(),
119 frame_width_, frame_height_); 120 clip.width(), clip.height());
120 121
121 XRenderFreePicture(display_, picture); 122 XRenderFreePicture(display_, picture);
122 XFreePixmap(display_, pixmap); 123 XFreePixmap(display_, pixmap);
123 } 124 }
124 125
125 void X11View::SetSolidFill(uint32 color) { 126 void X11View::SetSolidFill(uint32 color) {
126 // TODO(garykac): Implement. 127 // TODO(garykac): Implement.
127 // NOTIMPLEMENTED(); 128 // NOTIMPLEMENTED();
128 } 129 }
129 130
130 void X11View::UnsetSolidFill() { 131 void X11View::UnsetSolidFill() {
131 // TODO(garykac): Implement. 132 // TODO(garykac): Implement.
132 // NOTIMPLEMENTED(); 133 // NOTIMPLEMENTED();
133 } 134 }
134 135
135 void X11View::SetViewport(int x, int y, int width, int height) { 136 void X11View::SetViewport(int x, int y, int width, int height) {
136 // TODO(garykac): Implement. 137 // TODO(garykac): Implement.
137 // NOTIMPLEMENTED(); 138 // NOTIMPLEMENTED();
138 } 139 }
139 140
140 void X11View::SetHostScreenSize(int width, int height) {
141 frame_width_ = width;
142 frame_height_ = height;
143 frame_ = NULL;
144
145 XResizeWindow(display_, window_, frame_width_, frame_height_);
146 }
147
148 void X11View::InitPaintTarget() { 141 void X11View::InitPaintTarget() {
149 // Testing XRender support. 142 // Testing XRender support.
150 int dummy; 143 int dummy;
151 bool xrender_support = XRenderQueryExtension(display_, &dummy, &dummy); 144 bool xrender_support = XRenderQueryExtension(display_, &dummy, &dummy);
152 CHECK(xrender_support) << "XRender is not supported!"; 145 CHECK(xrender_support) << "XRender is not supported!";
153 146
154 XWindowAttributes attr; 147 XWindowAttributes attr;
155 XGetWindowAttributes(display_, window_, &attr); 148 XGetWindowAttributes(display_, window_, &attr);
156 149
157 XRenderPictFormat* pictformat = XRenderFindVisualFormat( 150 XRenderPictFormat* pictformat = XRenderFindVisualFormat(
158 display_, 151 display_,
159 attr.visual); 152 attr.visual);
160 CHECK(pictformat) << "XRENDER does not support default visual"; 153 CHECK(pictformat) << "XRENDER does not support default visual";
161 154
162 picture_ = XRenderCreatePicture(display_, window_, pictformat, 0, NULL); 155 picture_ = XRenderCreatePicture(display_, window_, pictformat, 0, NULL);
163 CHECK(picture_) << "Backing picture not created"; 156 CHECK(picture_) << "Backing picture not created";
164 } 157 }
165 158
166 void X11View::HandleBeginUpdateStream(ChromotingHostMessage* msg) { 159 void X11View::AllocateFrame(media::VideoFrame::Format format,
167 scoped_ptr<ChromotingHostMessage> deleter(msg); 160 size_t width,
161 size_t height,
162 base::TimeDelta timestamp,
163 base::TimeDelta duration,
164 scoped_refptr<media::VideoFrame>* frame_out,
165 Task* done) {
166 // TODO(ajwong): Implement this to use the native X window rather than
167 // just a generic frame buffer.
168 media::VideoFrame::CreateFrame(media::VideoFrame::RGB32,
169 width, height,
170 base::TimeDelta(), base::TimeDelta(),
171 frame_out);
172 if (*frame_out) {
173 (*frame_out)->AddRef();
174 }
175 done->Run();
176 delete done;
177 }
168 178
169 // Make sure the |frame_| is initialized. 179 void X11View::ReleaseFrame(media::VideoFrame* frame) {
170 if (!frame_) { 180 if (frame) {
171 media::VideoFrame::CreateFrame(media::VideoFrame::RGB32, 181 LOG(WARNING) << "Frame released.";
172 frame_width_, frame_height_, 182 frame->Release();
173 base::TimeDelta(), base::TimeDelta(),
174 &frame_);
175 CHECK(frame_);
176 } 183 }
177 } 184 }
178 185
179 void X11View::HandleUpdateStreamPacket(ChromotingHostMessage* msg) { 186 void X11View::OnPartialFrameOutput(media::VideoFrame* frame,
180 // Lazily initialize the decoder. 187 UpdatedRects* rects,
181 SetupDecoder(msg->update_stream_packet().begin_rect().encoding()); 188 Task* done) {
182 if (!decoder_->IsStarted()) {
183 BeginDecoding(NewRunnableMethod(this, &X11View::OnPartialDecodeDone),
184 NewRunnableMethod(this, &X11View::OnDecodeDone));
185 }
186
187 Decode(msg);
188 }
189
190 void X11View::HandleEndUpdateStream(ChromotingHostMessage* msg) {
191 scoped_ptr<ChromotingHostMessage> deleter(msg);
192 EndDecoding();
193 }
194
195 void X11View::OnPartialDecodeDone() {
196 // Decoder has produced some output so schedule a paint. We'll get a Paint()
197 // call in the near future. Note that we can get UpdateStreamPacket during
198 // this short period of time and we will perform decode again and the
199 // information in updated rects will be lost.
200 // There are several ways to solve this problem.
201 // 1. Merge the updated rects and perform one paint.
202 // 2. Queue the updated rects and perform two paints.
203 // 3. Ignore the updated rects and always paint the full image. Since we
204 // use one frame as output this will always be correct.
205 // We will take (1) and simply concat the list of rectangles.
206 all_update_rects_.insert(all_update_rects_.begin() +
207 all_update_rects_.size(),
208 update_rects_.begin(), update_rects_.end());
209
210 // TODO(hclam): Make sure we call this method on the right thread. Since 189 // TODO(hclam): Make sure we call this method on the right thread. Since
211 // decoder is single-threaded we don't have a problem but we better post 190 // decoder is single-threaded we don't have a problem but we better post
212 // a task to do the right thing. 191 // a task to do the right thing.
192
193 for (UpdatedRects::iterator it = rects->begin(); it != rects->end(); ++it) {
194 PaintRect(frame, *it);
195 }
196
197 // TODO(ajwong): Shouldn't we only expose the part of the window that was
198 // damanged?
213 XEvent event; 199 XEvent event;
214 event.type = Expose; 200 event.type = Expose;
215 XSendEvent(display_, static_cast<int>(window_), true, ExposureMask, &event); 201 XSendEvent(display_, static_cast<int>(window_), true, ExposureMask, &event);
216 }
217 202
218 void X11View::OnDecodeDone() { 203 done->Run();
219 // Since we do synchronous decoding here there's nothing in this method. 204 delete done;
220 } 205 }
221 206
222 } // namespace remoting 207 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/x11_view.h ('k') | remoting/host/capturer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698