Chromium Code Reviews| OLD | NEW |
|---|---|
| (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> | |
|
Daniel Erat
2011/04/02 14:54:36
nit: move this down just under where the gflags.h
marcheu
2011/04/04 19:55:58
Done.
| |
| 8 | |
| 9 #include <sys/time.h> | |
|
Daniel Erat
2011/04/02 14:54:36
i don't think you need this include, algorithm, ct
marcheu
2011/04/04 19:55:58
Done.
| |
| 10 | |
| 11 #include <algorithm> | |
| 12 #include <ctime> | |
| 13 #include <string> | |
| 14 | |
| 15 #include <gflags/gflags.h> | |
| 16 | |
| 17 #include "base/basictypes.h" | |
| 18 #include "base/logging.h" | |
| 19 #include "window_manager/image_container.h" | |
| 20 #include "window_manager/image_enums.h" | |
| 21 #include "window_manager/profiler.h" | |
|
Daniel Erat
2011/04/02 14:54:36
if you didn't use the profiling code while develop
marcheu
2011/04/04 19:55:58
Done.
| |
| 22 #include "window_manager/util.h" | |
| 23 #include "window_manager/x11/x_connection.h" | |
| 24 | |
| 25 | |
| 26 #ifndef COMPOSITOR_XRENDER | |
| 27 #error Need COMPOSITOR_XRENDER defined to compile this file | |
| 28 #endif | |
| 29 | |
| 30 using window_manager::util::XidStr; | |
|
Daniel Erat
2011/04/02 14:54:36
delete this; you don't use it
marcheu
2011/04/04 19:55:58
Done.
| |
| 31 | |
| 32 namespace window_manager { | |
| 33 | |
| 34 class XRenderPictureData : public TextureData { | |
| 35 public: | |
| 36 XRenderPictureData(XRenderDrawVisitor* visitor) { | |
| 37 pixmap_ = 0; | |
| 38 set_texture(0); | |
| 39 xconn_ = visitor->xconn(); | |
| 40 } | |
| 41 virtual ~XRenderPictureData() { | |
| 42 xconn_->RenderFreePicture (texture()); | |
|
Daniel Erat
2011/04/02 14:54:36
delete space between method name and paren
marcheu
2011/04/04 19:55:58
Done.
| |
| 43 } | |
| 44 | |
| 45 // Initialize our texture and make it contain the current contents of the | |
| 46 // passed-in actor's pixmap. False is returned if the process fails (in | |
|
Daniel Erat
2011/04/02 14:54:36
this comment is obsolete; no actor is being passed
marcheu
2011/04/04 19:55:58
Done.
| |
| 47 // which case this object should be thrown away). | |
| 48 bool Init(XPixmap pixmap, int bpp) { | |
| 49 set_texture( xconn_->RenderCreatePicture(pixmap, bpp) ); | |
|
Daniel Erat
2011/04/02 14:54:36
no spaces around function args
marcheu
2011/04/04 19:55:58
Done.
| |
| 50 return true; | |
| 51 } | |
| 52 | |
| 53 private: | |
| 54 // The actor's X pixmap. Ownership of the pixmap remains with the caller. | |
| 55 XPixmap pixmap_; | |
| 56 | |
| 57 XConnection* xconn_; // Not owned. | |
| 58 }; | |
| 59 | |
| 60 | |
| 61 XRenderDrawVisitor::XRenderDrawVisitor(RealCompositor* compositor, | |
| 62 Compositor::StageActor* stage) { | |
|
Daniel Erat
2011/04/02 14:54:36
make left edges of parameters line up
marcheu
2011/04/04 19:55:58
Done.
| |
| 63 xconn_ = compositor->x_conn(); | |
| 64 | |
| 65 // check for the XRender extension | |
|
Daniel Erat
2011/04/02 14:54:36
nit: fix capitalization and punctuation of this co
marcheu
2011/04/04 19:55:58
Done.
| |
| 66 if (!xconn_->RenderQueryExtension ()) { | |
|
Daniel Erat
2011/04/02 14:54:36
no space between method name and paren
you should
marcheu
2011/04/04 19:55:58
Done.
| |
| 67 LOG(ERROR) << "No render extension"; | |
| 68 } | |
| 69 | |
| 70 // find default depth | |
| 71 root_window = stage->GetStageXWindow(); | |
| 72 xconn_->GetWindowGeometry(root_window, &root_geometry); | |
| 73 | |
| 74 // create back pixmap | |
| 75 backPixmap = xconn_->CreatePixmap (root_window, | |
|
Daniel Erat
2011/04/02 14:54:36
fix style:
- no space between method name and pare
marcheu
2011/04/04 19:55:58
Done.
| |
| 76 Size(root_geometry.bounds.width, root_geometry.bounds.height), | |
| 77 root_geometry.depth); | |
| 78 backPicture = xconn_->RenderCreatePicture(backPixmap, 24); | |
|
Daniel Erat
2011/04/02 14:54:36
pull the "24" to a const at the top of the file
marcheu
2011/04/04 19:55:58
Done.
| |
| 79 // create stage pixmap | |
| 80 stagePicture = xconn_->RenderCreatePicture(root_window, 24); | |
| 81 } | |
| 82 | |
| 83 XRenderDrawVisitor::~XRenderDrawVisitor() { | |
| 84 } | |
| 85 | |
| 86 void XRenderDrawVisitor::BindImage(const ImageContainer* container, | |
| 87 RealCompositor::ImageActor* actor) { | |
|
Daniel Erat
2011/04/02 14:54:36
align with param on previous line
marcheu
2011/04/04 19:55:58
Done.
| |
| 88 XPixmap pixmap = xconn_->CreatePixmapFromData( (char*)container->data(), | |
|
Daniel Erat
2011/04/02 14:54:36
fix indenting
marcheu
2011/04/04 19:55:58
Done.
| |
| 89 Size(container->width(), container->height())); | |
|
Daniel Erat
2011/04/02 14:54:36
i added an Actor::GetBounds() method, so you shoul
marcheu
2011/04/04 19:55:58
ImageContainer is not an actor, so I added a GetSi
| |
| 90 | |
| 91 XRenderPictureData* data = new XRenderPictureData(this); | |
| 92 data->Init(pixmap, 32); | |
| 93 actor->set_texture_data(data); | |
| 94 } | |
| 95 | |
| 96 void XRenderDrawVisitor::VisitImage(RealCompositor::ImageActor* actor) { | |
| 97 if (!actor->IsVisible()) | |
| 98 return; | |
| 99 | |
| 100 PROFILER_MARKER_BEGIN(VisitImage); | |
| 101 | |
| 102 // All ImageActors are also QuadActors, and so we let the | |
| 103 // QuadActor do all the actual drawing. | |
| 104 VisitQuad(actor); | |
| 105 PROFILER_MARKER_END(VisitImage); | |
| 106 } | |
| 107 | |
| 108 void XRenderDrawVisitor::VisitTexturePixmap( | |
| 109 RealCompositor::TexturePixmapActor* actor) { | |
| 110 if (!actor->IsVisible()) | |
| 111 return; | |
| 112 | |
| 113 PROFILER_MARKER_BEGIN(VisitTexturePixmap); | |
| 114 | |
| 115 // Make sure we have an XRender pic for this pixmap | |
| 116 if (!actor->texture_data()) { | |
| 117 if (actor->pixmap()) { | |
| 118 XRenderPictureData* data = new XRenderPictureData(this); | |
| 119 data->Init(actor->pixmap(), actor->pixmap_is_opaque() ? 24:32); | |
|
Daniel Erat
2011/04/02 14:54:36
fix spacing: only one space after comma, and add s
marcheu
2011/04/04 19:55:58
Done.
| |
| 120 actor->set_texture_data(data); | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 // All texture pixmaps are also QuadActors, and so we let the | |
| 125 // QuadActor do all the actual drawing. | |
| 126 VisitQuad(actor); | |
| 127 PROFILER_MARKER_END(VisitTexturePixmap); | |
| 128 } | |
| 129 | |
| 130 void XRenderDrawVisitor::VisitQuad(RealCompositor::QuadActor* actor) { | |
| 131 if (!actor->IsVisible()) | |
| 132 return; | |
| 133 | |
| 134 #ifdef EXTRA_LOGGING | |
| 135 DLOG(INFO) << "Drawing quad " << actor->name() << "."; | |
| 136 #endif | |
| 137 PROFILER_DYNAMIC_MARKER_BEGIN(actor->name().c_str()); | |
| 138 | |
| 139 // Calculate the vertex colors, taking into account the actor color, | |
| 140 // opacity and the dimming gradient. | |
| 141 float actor_opacity = actor->is_opaque() ? 1.0f : | |
|
Daniel Erat
2011/04/02 14:54:36
nit: move "1.0f :" to its own line
marcheu
2011/04/04 19:55:58
Done.
| |
| 142 actor->opacity() * ancestor_opacity_; | |
| 143 float dimmed_transparency_begin = 1.f - actor->dimmed_opacity_begin(); | |
| 144 float dimmed_transparency_end = 1.f - actor->dimmed_opacity_end(); | |
| 145 float red = actor->color().red; | |
| 146 float green = actor->color().green; | |
| 147 float blue = actor->color().blue; | |
| 148 DCHECK_LE(actor_opacity, 1.f); | |
| 149 DCHECK_GE(actor_opacity, 0.f); | |
| 150 DCHECK_LE(dimmed_transparency_begin, 1.f); | |
| 151 DCHECK_GE(dimmed_transparency_begin, 0.f); | |
| 152 DCHECK_LE(dimmed_transparency_end, 1.f); | |
| 153 DCHECK_GE(dimmed_transparency_end, 0.f); | |
| 154 DCHECK_LE(red, 1.f); | |
| 155 DCHECK_GE(red, 0.f); | |
| 156 DCHECK_LE(green, 1.f); | |
| 157 DCHECK_GE(green, 0.f); | |
| 158 DCHECK_LE(blue, 1.f); | |
| 159 DCHECK_GE(blue, 0.f); | |
| 160 | |
| 161 xconn_->RenderComposite (!actor->is_opaque(), | |
|
Daniel Erat
2011/04/02 14:54:36
remove space before paren
marcheu
2011/04/04 19:55:58
Done.
| |
| 162 (XPicture)actor->texture_data()->texture(), | |
|
Daniel Erat
2011/04/02 14:54:36
use c++ style casts (static_cast<XPicture>(...))
marcheu
2011/04/04 19:55:58
Done.
| |
| 163 (XPicture)None, backPicture, | |
|
Daniel Erat
2011/04/02 14:54:36
one arg per line except for stuff like x, y and wi
marcheu
2011/04/04 19:55:58
Done.
| |
| 164 Point(0, 0), | |
| 165 Point(0, 0), | |
| 166 actor->model_view(), | |
| 167 Size(actor->width(), actor->height()) | |
|
Daniel Erat
2011/04/02 14:54:36
GetBounds().size()
marcheu
2011/04/04 19:55:58
Done.
| |
| 168 ); | |
|
Daniel Erat
2011/04/02 14:54:36
move to end of previous line
marcheu
2011/04/04 19:55:58
Done.
| |
| 169 | |
| 170 PROFILER_DYNAMIC_MARKER_END(); | |
| 171 } | |
| 172 | |
| 173 | |
| 174 void XRenderDrawVisitor::VisitStage(RealCompositor::StageActor* actor) { | |
| 175 if (!actor->IsVisible()) return; | |
|
Daniel Erat
2011/04/02 14:54:36
move 'return' to its own line
marcheu
2011/04/04 19:55:58
Done.
| |
| 176 | |
| 177 PROFILER_MARKER_BEGIN(VisitStage); | |
| 178 stage_ = actor; | |
| 179 | |
| 180 if (actor->was_resized()) { | |
|
Daniel Erat
2011/04/02 14:54:36
chrome style is to not use curly braces for ifs wi
marcheu
2011/04/04 19:55:58
Done.
| |
| 181 actor->unset_was_resized(); | |
| 182 } | |
| 183 | |
| 184 // If we don't have a full screen actor we do a fill with the stage color. | |
| 185 if (!has_fullscreen_actor_) | |
| 186 { | |
|
Daniel Erat
2011/04/02 14:54:36
move '{' to end of previous line
marcheu
2011/04/04 19:55:58
Done.
| |
| 187 const Compositor::Color& color = actor->stage_color(); | |
| 188 xconn_->RenderFillRectangle(backPicture, color.red, color.green, color.blue, | |
| 189 Point(0, 0), | |
|
Daniel Erat
2011/04/02 14:54:36
fix indenting
marcheu
2011/04/04 19:55:58
Done.
| |
| 190 Size(root_geometry.bounds.width, root_geometry.bounds.height) | |
|
Daniel Erat
2011/04/02 14:54:36
root_geometry.bounds.size()
marcheu
2011/04/04 19:55:58
Done.
| |
| 191 ); | |
|
Daniel Erat
2011/04/02 14:54:36
move to end of previous line
marcheu
2011/04/04 19:55:58
Done.
| |
| 192 } | |
| 193 | |
| 194 #ifdef EXTRA_LOGGING | |
| 195 DLOG(INFO) << "Starting Render pass."; | |
| 196 #endif | |
| 197 | |
| 198 ancestor_opacity_ = actor->opacity(); | |
| 199 | |
| 200 // Walk the actors and render them | |
| 201 PROFILER_MARKER_BEGIN(Render_Pass); | |
| 202 VisitContainer(actor); | |
| 203 PROFILER_MARKER_END(Render_Pass); | |
| 204 | |
| 205 #ifdef EXTRA_LOGGING | |
| 206 DLOG(INFO) << "Ending Render pass."; | |
| 207 #endif | |
| 208 | |
| 209 PROFILER_MARKER_BEGIN(Swap_Buffer); | |
| 210 if ( !damaged_region_.empty() ) { | |
|
Daniel Erat
2011/04/02 14:54:36
remove extra spaces
marcheu
2011/04/04 19:55:58
Done.
| |
| 211 Matrix4 identity = Vectormath::Aos::Matrix4::identity(); | |
| 212 identity[0][0] = damaged_region_.width; | |
| 213 identity[1][1] = damaged_region_.height; | |
| 214 identity[3][0] = damaged_region_.x; | |
| 215 identity[3][1] = root_geometry.bounds.height | |
| 216 - damaged_region_.y - damaged_region_.height; | |
|
Daniel Erat
2011/04/02 14:54:36
move initial '-' to end of previous line
marcheu
2011/04/04 19:55:58
Done.
| |
| 217 xconn_->RenderComposite (false, | |
| 218 backPicture, | |
|
Daniel Erat
2011/04/02 14:54:36
fix indenting
marcheu
2011/04/04 19:55:58
Done.
| |
| 219 None, | |
| 220 stagePicture, | |
| 221 Point(damaged_region_.x, | |
| 222 root_geometry.bounds.height | |
|
Daniel Erat
2011/04/02 14:54:36
fix indenting
marcheu
2011/04/04 19:55:58
Done.
| |
| 223 - damaged_region_.y | |
|
Daniel Erat
2011/04/02 14:54:36
put operators at end of lines instead of beginning
marcheu
2011/04/04 19:55:58
Done.
| |
| 224 - damaged_region_.height), | |
| 225 Point(0, 0), | |
| 226 identity, | |
| 227 Size(damaged_region_.width, damaged_region_.height) | |
|
Daniel Erat
2011/04/02 14:54:36
damaged_region_.size()
marcheu
2011/04/04 19:55:58
Done.
| |
| 228 ); | |
|
Daniel Erat
2011/04/02 14:54:36
move to end of previous line
marcheu
2011/04/04 19:55:58
Done.
| |
| 229 } | |
| 230 else | |
| 231 { | |
|
Daniel Erat
2011/04/02 14:54:36
move to end of previous line
marcheu
2011/04/04 19:55:58
Done.
| |
| 232 Matrix4 identity = Vectormath::Aos::Matrix4::identity(); | |
| 233 identity[0][0] = root_geometry.bounds.width; | |
| 234 identity[1][1] = root_geometry.bounds.height; | |
| 235 xconn_->RenderComposite (false, | |
| 236 backPicture, | |
|
Daniel Erat
2011/04/02 14:54:36
fix indenting
marcheu
2011/04/04 19:55:58
Done.
| |
| 237 None, | |
| 238 stagePicture, | |
| 239 Point(0, 0), | |
| 240 Point(0, 0), | |
| 241 identity, | |
| 242 Size(root_geometry.bounds.width, root_geometry.bounds.height) | |
|
Daniel Erat
2011/04/02 14:54:36
size()
marcheu
2011/04/04 19:55:58
Done.
| |
| 243 ); | |
|
Daniel Erat
2011/04/02 14:54:36
you get the idea
marcheu
2011/04/04 19:55:58
Done.
| |
| 244 } | |
| 245 | |
| 246 PROFILER_MARKER_END(Swap_Buffer); | |
| 247 ++num_frames_drawn_; | |
| 248 | |
| 249 PROFILER_MARKER_END(VisitStage); | |
| 250 // The profiler is flushed explicitly every 100 frames, or flushed | |
| 251 // implicitly when the internal buffer is full. | |
| 252 if (num_frames_drawn_ % 100 == 0) | |
| 253 PROFILER_FLUSH(); | |
| 254 stage_ = NULL; | |
| 255 } | |
| 256 | |
| 257 void XRenderDrawVisitor::VisitContainer(RealCompositor::ContainerActor* actor) { | |
| 258 if (!actor->IsVisible()) | |
| 259 return; | |
| 260 | |
| 261 #ifdef EXTRA_LOGGING | |
| 262 DLOG(INFO) << "Drawing container " << actor->name() << "."; | |
| 263 DLOG(INFO) << " at: (" << actor->x() << ", " << actor->y() | |
| 264 << ", " << actor->z() << ") with scale: (" | |
| 265 << actor->scale_x() << ", " << actor->scale_y() << ") at size (" | |
| 266 << actor->width() << "x" << actor->height() << ")"; | |
| 267 #endif | |
| 268 RealCompositor::ActorVector children = actor->GetChildren(); | |
| 269 | |
| 270 { | |
|
Daniel Erat
2011/04/02 14:54:36
this should be indented one more space, but do you
marcheu
2011/04/04 19:55:58
Done.
| |
| 271 float original_opacity = ancestor_opacity_; | |
| 272 ancestor_opacity_ *= actor->opacity(); | |
| 273 | |
| 274 // Walk backwards so we go back to front. | |
| 275 RealCompositor::ActorVector::const_reverse_iterator iterator; | |
| 276 for (iterator = children.rbegin(); iterator != children.rend(); | |
| 277 ++iterator) { | |
| 278 RealCompositor::Actor* child = *iterator; | |
| 279 | |
| 280 if (child->IsVisible()) { | |
| 281 #ifdef EXTRA_LOGGING | |
| 282 DLOG(INFO) << "Drawing transparent child " << child->name() | |
| 283 << " (visible: " << child->IsVisible() | |
| 284 << ", has_children: " << child->has_children() | |
| 285 << ", opacity: " << child->opacity() | |
| 286 << ", ancestor_opacity: " << ancestor_opacity_ | |
| 287 << ", is_opaque: " << child->is_opaque() << ")"; | |
| 288 #endif | |
| 289 child->Accept(this); | |
| 290 } else { | |
| 291 #ifdef EXTRA_LOGGING | |
| 292 DLOG(INFO) << "NOT drawing opaque child " << child->name() | |
| 293 << " (visible: " << child->IsVisible() | |
| 294 << ", has_children: " << child->has_children() | |
| 295 << ", opacity: " << child->opacity() | |
| 296 << ", ancestor_opacity: " << ancestor_opacity_ | |
| 297 << ", is_opaque: " << child->is_opaque() << ")"; | |
| 298 #endif | |
| 299 } | |
| 300 } | |
| 301 | |
| 302 // Reset ancestor opacity. | |
| 303 ancestor_opacity_ = original_opacity; | |
| 304 } | |
| 305 } | |
| 306 | |
| 307 } // namespace window_manager | |
| OLD | NEW |