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

Side by Side Diff: compositor/xrender/xrender_visitor.cc

Issue 6793005: Add the xrender backend to the window manager. (Closed) Base URL: ssh://gitrw.chromium.org:9222/window_manager.git@master
Patch Set: Add missing trailing _ to root_window and root_geometry. Created 9 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium OS 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 "window_manager/compositor/xrender/xrender_visitor.h"
6
7 #include <X11/extensions/Xrender.h>
8
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "base/scoped_ptr.h"
12 #include "window_manager/image_container.h"
13 #include "window_manager/image_enums.h"
14 #include "window_manager/util.h"
15 #include "window_manager/x11/x_connection.h"
16
17
18 #ifndef COMPOSITOR_XRENDER
19 #error Need COMPOSITOR_XRENDER defined to compile this file
20 #endif
21
22 namespace window_manager {
23
24 const int kRGBPictureBitDepth = 24;
25 const int kRGBAPictureBitDepth = 32;
26
27 class XRenderPictureData : public TextureData {
28 public:
29 XRenderPictureData(XConnection* xconn)
30 : pixmap_(0),
31 xconn_(xconn) {
32 }
33 virtual ~XRenderPictureData() {
34 xconn_->RenderFreePicture(texture());
35 }
36
37 // Initialize our texture and make it contain the current contents of the
38 // passed-in pixmap. False is returned if the process fails (in
39 // which case this object should be thrown away).
40 bool Init(XPixmap pixmap, int bpp) {
41 XPicture picture = xconn_->RenderCreatePicture(pixmap, bpp);
42 set_texture(picture);
43 return (picture != None);
44 }
45
46 private:
47 // The actor's X pixmap. Ownership of the pixmap remains with the caller.
48 XPixmap pixmap_;
49
50 XConnection* xconn_; // Not owned.
51 };
52
53 bool XRenderDrawVisitor::FreeXResources() {
Daniel Erat 2011/04/05 01:35:06 move this and AllocateXResources() down. the meth
marcheu 2011/04/05 02:07:42 Done.
54 return xconn_->FreePixmap(back_pixmap_) &&
55 xconn_->RenderFreePicture(back_picture_) &&
Daniel Erat 2011/04/05 01:35:06 fix indenting: line this up with the xconn_ on the
marcheu 2011/04/05 02:07:42 Done.
56 xconn_->RenderFreePicture(stage_picture_);
57 }
58
59 bool XRenderDrawVisitor::AllocateXResources(Compositor::StageActor* stage) {
60 // Find root window geometry.
61 root_window_ = stage->GetStageXWindow();
62 xconn_->GetWindowGeometry(root_window_, &root_geometry_);
63
64 // Create back pixmap.
65 back_pixmap_ =
66 xconn_->CreatePixmap(
67 root_window_,
68 root_geometry_.bounds.size(),
69 root_geometry_.depth);
70
71 // Create back picture.
72 back_picture_ = xconn_->RenderCreatePicture(back_pixmap_,
73 kRGBPictureBitDepth);
74
75 // Create stage picture.
76 stage_picture_ = xconn_->RenderCreatePicture(root_window_,
77 kRGBPictureBitDepth);
78
79 return (back_pixmap_ != None) &&
80 (back_picture_ != None) &&
81 (stage_picture_ != None);
82 }
83
84
85 XRenderDrawVisitor::XRenderDrawVisitor(RealCompositor* compositor,
86 Compositor::StageActor* stage)
87 : root_window_(None),
88 root_geometry_(),
Daniel Erat 2011/04/05 01:35:06 nit: no need to list objects with reasonable defau
marcheu 2011/04/05 02:07:42 Done.
89 back_picture_(None),
90 back_pixmap_(None),
91 stage_picture_(None),
92 compositor_(NULL),
93 xconn_(compositor->x_conn()),
94 stage_(NULL),
95 ancestor_opacity_(1.0),
96 has_fullscreen_actor_(false) {
97 // Check for the XRender extension.
98 CHECK(xconn_->RenderQueryExtension());
99
100 CHECK(AllocateXResources(stage));
101 }
102
103 XRenderDrawVisitor::~XRenderDrawVisitor() {
Daniel Erat 2011/04/05 01:35:06 call FreeXResources() here
marcheu 2011/04/05 02:07:42 Done.
104 }
105
106 void XRenderDrawVisitor::BindImage(const ImageContainer* container,
107 RealCompositor::ImageActor* actor) {
108 XPixmap pixmap = xconn_->CreatePixmapFromContainer(*container);
109
110 scoped_ptr<window_manager::XRenderPictureData>
111 data(new XRenderPictureData(this->xconn_));
112 data->Init(pixmap, kRGBAPictureBitDepth);
113 actor->set_texture_data(data.release());
114 }
115
116 void XRenderDrawVisitor::VisitImage(RealCompositor::ImageActor* actor) {
117 if (!actor->IsVisible())
118 return;
119
120 // All ImageActors are also QuadActors, and so we let the
121 // QuadActor do all the actual drawing.
122 VisitQuad(actor);
123 }
124
125 void XRenderDrawVisitor::VisitTexturePixmap(
126 RealCompositor::TexturePixmapActor* actor) {
127 if (!actor->IsVisible())
128 return;
129
130 // Make sure we have an XRender pic for this pixmap
131 if (!actor->texture_data()) {
132 if (actor->pixmap()) {
133 scoped_ptr<window_manager::XRenderPictureData>
134 data(new XRenderPictureData(this->xconn_));
135 data->Init(actor->pixmap(),
136 actor->pixmap_is_opaque() ?
137 kRGBPictureBitDepth : kRGBAPictureBitDepth);
138 actor->set_texture_data(data.release());
139 }
140 }
141
142 // All texture pixmaps are also QuadActors, and so we let the
143 // QuadActor do all the actual drawing.
144 VisitQuad(actor);
145 }
146
147 void XRenderDrawVisitor::VisitQuad(RealCompositor::QuadActor* actor) {
148 if (!actor->IsVisible())
149 return;
150
151 #ifdef EXTRA_LOGGING
152 DLOG(INFO) << "Drawing quad " << actor->name() << ".";
153 #endif
154
155 // Calculate the vertex colors, taking into account the actor color,
156 // opacity and the dimming gradient.
157 float actor_opacity = actor->is_opaque() ?
158 1.f :
159 actor->opacity() * ancestor_opacity_;
160 float dimmed_transparency_begin = 1.f - actor->dimmed_opacity_begin();
161 float dimmed_transparency_end = 1.f - actor->dimmed_opacity_end();
162 float red = actor->color().red;
163 float green = actor->color().green;
164 float blue = actor->color().blue;
165 DCHECK_LE(actor_opacity, 1.f);
166 DCHECK_GE(actor_opacity, 0.f);
167 DCHECK_LE(dimmed_transparency_begin, 1.f);
168 DCHECK_GE(dimmed_transparency_begin, 0.f);
169 DCHECK_LE(dimmed_transparency_end, 1.f);
170 DCHECK_GE(dimmed_transparency_end, 0.f);
171 DCHECK_LE(red, 1.f);
172 DCHECK_GE(red, 0.f);
173 DCHECK_LE(green, 1.f);
174 DCHECK_GE(green, 0.f);
175 DCHECK_LE(blue, 1.f);
176 DCHECK_GE(blue, 0.f);
177
178 xconn_->RenderComposite(
179 !actor->is_opaque(),
180 static_cast<XPicture>(actor->texture_data()->texture()),
181 static_cast<XPicture>(None),
182 back_picture_,
183 Point(0, 0),
184 Point(0, 0),
185 actor->model_view(),
186 actor->GetBounds().size());
187 }
188
189 void XRenderDrawVisitor::VisitStage(RealCompositor::StageActor* actor) {
190 if (!actor->IsVisible())
191 return;
192
193 stage_ = actor;
194
195 if (actor->was_resized()) {
196 CHECK(FreeXResources());
197 CHECK(AllocateXResources(actor));
198 actor->unset_was_resized();
199 }
200
201 // If we don't have a full screen actor we do a fill with the stage color.
202 if (!has_fullscreen_actor_) {
203 const Compositor::Color& color = actor->stage_color();
204 xconn_->RenderFillRectangle(back_picture_,
205 color.red,
206 color.green,
207 color.blue,
208 Point(0, 0),
209 root_geometry_.bounds.size());
210 }
211
212 #ifdef EXTRA_LOGGING
213 DLOG(INFO) << "Starting Render pass.";
214 #endif
215
216 ancestor_opacity_ = actor->opacity();
217
218 // Walk the actors and render them
219 VisitContainer(actor);
220
221 #ifdef EXTRA_LOGGING
222 DLOG(INFO) << "Ending Render pass.";
223 #endif
224
225 if (!damaged_region_.empty()) {
226 Matrix4 identity = Matrix4::identity();
227 identity[0][0] = damaged_region_.width;
228 identity[1][1] = damaged_region_.height;
229 identity[3][0] = damaged_region_.x;
230 identity[3][1] = root_geometry_.bounds.height -
231 damaged_region_.y - damaged_region_.height;
232
233 xconn_->RenderComposite(false,
234 back_picture_,
235 None,
236 stage_picture_,
237 Point(damaged_region_.x,
238 root_geometry_.bounds.height -
239 damaged_region_.y -
240 damaged_region_.height),
241 Point(0, 0),
242 identity,
243 damaged_region_.size());
244 } else {
245 Matrix4 identity = Vectormath::Aos::Matrix4::identity();
246 identity[0][0] = root_geometry_.bounds.width;
247 identity[1][1] = root_geometry_.bounds.height;
248 xconn_->RenderComposite(false,
249 back_picture_,
250 None,
251 stage_picture_,
252 Point(0, 0),
253 Point(0, 0),
254 identity,
255 root_geometry_.bounds.size());
256 }
257
258 stage_ = NULL;
259 }
260
261 void XRenderDrawVisitor::VisitContainer(RealCompositor::ContainerActor* actor) {
262 if (!actor->IsVisible())
263 return;
264
265 #ifdef EXTRA_LOGGING
266 DLOG(INFO) << "Drawing container " << actor->name() << ".";
267 DLOG(INFO) << " at: (" << actor->x() << ", " << actor->y()
268 << ", " << actor->z() << ") with scale: ("
269 << actor->scale_x() << ", " << actor->scale_y() << ") at size ("
270 << actor->width() << "x" << actor->height() << ")";
271 #endif
272 RealCompositor::ActorVector children = actor->GetChildren();
273
274 float original_opacity = ancestor_opacity_;
275 ancestor_opacity_ *= actor->opacity();
276
277 // Walk backwards so we go back to front.
278 RealCompositor::ActorVector::const_reverse_iterator iterator;
279 for (iterator = children.rbegin(); iterator != children.rend();
280 ++iterator) {
281 RealCompositor::Actor* child = *iterator;
282
283 if (child->IsVisible()) {
284 #ifdef EXTRA_LOGGING
285 DLOG(INFO) << "Drawing child " << child->name()
286 << " (visible: " << child->IsVisible()
287 << ", has_children: " << child->has_children()
288 << ", opacity: " << child->opacity()
289 << ", ancestor_opacity: " << ancestor_opacity_
290 << ", is_opaque: " << child->is_opaque() << ")";
291 #endif
292 child->Accept(this);
293 } else {
294 #ifdef EXTRA_LOGGING
295 DLOG(INFO) << "NOT drawing child " << child->name()
296 << " (visible: " << child->IsVisible()
297 << ", has_children: " << child->has_children()
298 << ", opacity: " << child->opacity()
299 << ", ancestor_opacity: " << ancestor_opacity_
300 << ", is_opaque: " << child->is_opaque() << ")";
301 #endif
302 }
303
304 // Reset ancestor opacity.
305 ancestor_opacity_ = original_opacity;
306 }
307 }
308
309 } // namespace window_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698