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

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

Issue 2745006: Implement a chromoting client using X11 (Closed)
Patch Set: removed all.gyp Created 10 years, 6 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.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "remoting/client/x11_view.h"
6
7 #include <X11/Xlib.h>
8 #include <X11/Xutil.h>
9 #include <X11/extensions/Xrender.h>
10 #include <X11/extensions/Xcomposite.h>
11 #include "remoting/client/decoder_verbatim.h"
12
13 namespace remoting {
14
15 X11View::X11View(Display* display, int window, int width, int height)
16 : display_(display),
17 window_(window),
18 picture_(0),
19 width_(width),
20 height_(height) {
21 }
22
23 X11View::~X11View() {
24 }
25
26 void X11View::Paint() {
27 // TODO(hclam): Paint only the updated regions.
28 all_update_rects_.clear();
29
30 // If we have not initialized the render target then do it now.
31 if (!frame_)
32 InitPaintTarget();
33
34 // Upload the image to a pixmap. And then creats a picture from the pixmap
35 // and composite the picture over the picture represending the window.
36
37 // Creates a XImage.
38 XImage image;
39 memset(&image, 0, sizeof(image));
40 image.width = width_;
41 image.height = height_;
42 image.depth = 32;
43 image.bits_per_pixel = 32;
44 image.format = ZPixmap;
45 image.byte_order = LSBFirst;
46 image.bitmap_unit = 8;
47 image.bitmap_bit_order = LSBFirst;
48 image.bytes_per_line = frame_->stride(media::VideoFrame::kRGBPlane);
49 image.red_mask = 0xff;
50 image.green_mask = 0xff00;
51 image.blue_mask = 0xff0000;
52 image.data = reinterpret_cast<char*>(
53 frame_->data(media::VideoFrame::kRGBPlane));
54
55 // Creates a pixmap and uploads from the XImage.
56 unsigned long pixmap = XCreatePixmap(display_, window_, width_, height_, 32);
57
58 GC gc = XCreateGC(display_, pixmap, 0, NULL);
59 XPutImage(display_, pixmap, gc, &image, 0, 0, 0, 0, width_, height_);
60 XFreeGC(display_, gc);
61
62 // Creates the picture representing the pixmap.
63 unsigned long picture = XRenderCreatePicture(
64 display_, pixmap,
65 XRenderFindStandardFormat(display_, PictStandardARGB32),
66 0, NULL);
67
68 // Composite the picture over the picture representing the window.
69 XRenderComposite(display_, PictOpSrc, picture, 0,
70 picture_, 0, 0, 0, 0, 0, 0,
71 width_, height_);
72
73 XRenderFreePicture(display_, picture);
74 XFreePixmap(display_, pixmap);
75 }
76
77 void X11View::InitPaintTarget() {
78 // Testing XRender support.
79 int dummy;
80 bool xrender_support = XRenderQueryExtension(display_, &dummy, &dummy);
81 CHECK(xrender_support) << "XRender is not supported!";
82
83 XWindowAttributes attr;
84 XGetWindowAttributes(display_, window_, &attr);
85
86 XRenderPictFormat* pictformat = XRenderFindVisualFormat(
87 display_,
88 attr.visual);
89 CHECK(pictformat) << "XRENDER does not support default visual";
90
91 picture_ = XRenderCreatePicture(display_, window_, pictformat, 0, NULL);
92 CHECK(picture_) << "Backing picture not created";
93
94 // Create the video frame to carry the decoded image.
95 media::VideoFrame::CreateFrame(media::VideoFrame::RGB32, width_, height_,
96 base::TimeDelta(), base::TimeDelta(), &frame_);
97 DCHECK(frame_);
98 }
99
100 void X11View::HandleBeginUpdateStream(HostMessage* msg) {
101 scoped_ptr<HostMessage> deleter(msg);
102
103 // TODO(hclam): Use the information from the message to create the decoder.
104 // We lazily construct the decoder.
105 if (!decoder_.get()) {
106 decoder_.reset(new DecoderVerbatim());
107 }
108
109 // Tell the decoder to do start decoding.
110 decoder_->BeginDecode(frame_, &update_rects_,
111 NewRunnableMethod(this, &X11View::OnPartialDecodeDone),
112 NewRunnableMethod(this, &X11View::OnDecodeDone));
113 }
114
115 void X11View::HandleUpdateStreamPacket(HostMessage* msg) {
116 decoder_->PartialDecode(msg);
117 }
118
119 void X11View::HandleEndUpdateStream(HostMessage* msg) {
120 scoped_ptr<HostMessage> deleter(msg);
121 decoder_->EndDecode();
122 }
123
124 void X11View::OnPartialDecodeDone() {
125 // Decoder has produced some output so schedule a paint. We'll get a Paint()
126 // call in the short future. Note that we can get UpdateStreamPacket during
127 // this short period of time and we will perform decode again and the
128 // information of updated rects will be lost.
129 // There are several ways to solve this problem.
130 // 1. Merge the updated rects and perform one paint.
131 // 2. Queue the updated rects and perform two paints.
132 // 3. Ignore the updated rects and always paint the full image. Since we
133 // use one frame as output this will always be correct.
134 // We will take (1) and simply concat the list of rectangles.
135 all_update_rects_.insert(all_update_rects_.begin() +
136 all_update_rects_.size(),
137 update_rects_.begin(), update_rects_.end());
138
139 // TODO(hclam): Make sure we call this method on the right thread. Since
140 // decoder is single-threaded we don't have a problem but we better post
141 // a task to do the right thing.
142 XEvent event;
143 event.type = Expose;
144 XSendEvent(display_, static_cast<int>(window_), true, ExposureMask, &event);
145 }
146
147 void X11View::OnDecodeDone() {
148 // Since we do synchronous decoding here there's nothing in this method.
149 }
150
151 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/x11_view.h ('k') | remoting/host/capturer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698