OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS 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 "window_manager/compositor/gles/opengles_visitor.h" | 5 #include "window_manager/compositor/gles/opengles_visitor.h" |
6 | 6 |
7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
8 #include <xcb/damage.h> | 8 #include <xcb/damage.h> |
9 | 9 |
10 #include <EGL/egl.h> | 10 #include <EGL/egl.h> |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 EGL_NO_SURFACE, | 134 EGL_NO_SURFACE, |
135 EGL_NO_SURFACE, | 135 EGL_NO_SURFACE, |
136 EGL_NO_CONTEXT) != EGL_TRUE) | 136 EGL_NO_CONTEXT) != EGL_TRUE) |
137 << "eglMakeCurrent() failed: " << eglGetError(); | 137 << "eglMakeCurrent() failed: " << eglGetError(); |
138 LOG_IF(ERROR, gl_->EglDestroySurface(egl_display_, egl_surface_) != EGL_TRUE) | 138 LOG_IF(ERROR, gl_->EglDestroySurface(egl_display_, egl_surface_) != EGL_TRUE) |
139 << "eglDestroySurface() failed: " << eglGetError(); | 139 << "eglDestroySurface() failed: " << eglGetError(); |
140 LOG_IF(ERROR, gl_->EglDestroyContext(egl_display_, egl_context_) != EGL_TRUE) | 140 LOG_IF(ERROR, gl_->EglDestroyContext(egl_display_, egl_context_) != EGL_TRUE) |
141 << "eglDestroyCotnext() failed: " << eglGetError(); | 141 << "eglDestroyCotnext() failed: " << eglGetError(); |
142 } | 142 } |
143 | 143 |
144 void OpenGlesDrawVisitor::BindImage(const ImageContainer* container, | 144 void OpenGlesDrawVisitor::BindImage(const ImageContainer& container, |
145 RealCompositor::QuadActor* actor) { | 145 RealCompositor::QuadActor* actor) { |
146 // TODO: Check container->format() and use a shader to swizzle BGR | 146 // TODO: Check container.format() and use a shader to swizzle BGR |
147 // data into RGB. | 147 // data into RGB. |
148 GLenum gl_format = 0; | 148 GLenum gl_format = 0; |
149 GLenum gl_type = 0; | 149 GLenum gl_type = 0; |
150 switch (container->format()) { | 150 switch (container.format()) { |
151 case IMAGE_FORMAT_RGBA_32: | 151 case IMAGE_FORMAT_RGBA_32: |
152 case IMAGE_FORMAT_RGBX_32: | 152 case IMAGE_FORMAT_RGBX_32: |
153 gl_format = GL_RGBA; | 153 gl_format = GL_RGBA; |
154 gl_type = GL_UNSIGNED_BYTE; | 154 gl_type = GL_UNSIGNED_BYTE; |
155 break; | 155 break; |
156 case IMAGE_FORMAT_BGRA_32: | 156 case IMAGE_FORMAT_BGRA_32: |
157 case IMAGE_FORMAT_BGRX_32: | 157 case IMAGE_FORMAT_BGRX_32: |
158 NOTIMPLEMENTED() << "BGR-order image data unsupported"; | 158 NOTIMPLEMENTED() << "BGR-order image data unsupported"; |
159 gl_format = GL_RGBA; | 159 gl_format = GL_RGBA; |
160 gl_type = GL_UNSIGNED_BYTE; | 160 gl_type = GL_UNSIGNED_BYTE; |
161 break; | 161 break; |
162 case IMAGE_FORMAT_RGB_16: | 162 case IMAGE_FORMAT_RGB_16: |
163 gl_format = GL_RGB; | 163 gl_format = GL_RGB; |
164 gl_type = GL_UNSIGNED_SHORT_5_6_5; | 164 gl_type = GL_UNSIGNED_SHORT_5_6_5; |
165 break; | 165 break; |
166 default: | 166 default: |
167 NOTREACHED() << "Invalid image data format"; | 167 NOTREACHED() << "Invalid image data format"; |
168 break; | 168 break; |
169 } | 169 } |
170 | 170 |
171 GLuint texture = 0; | 171 GLuint texture = 0; |
172 gl_->GenTextures(1, &texture); | 172 gl_->GenTextures(1, &texture); |
173 CHECK(texture > 0) << "Failed to allocated texture."; | 173 CHECK(texture > 0) << "Failed to allocated texture."; |
174 gl_->BindTexture(GL_TEXTURE_2D, texture); | 174 gl_->BindTexture(GL_TEXTURE_2D, texture); |
175 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 175 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
176 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 176 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
177 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 177 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
178 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 178 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
179 gl_->TexImage2D(GL_TEXTURE_2D, 0, gl_format, | 179 gl_->TexImage2D(GL_TEXTURE_2D, 0, gl_format, |
180 container->width(), container->height(), | 180 container.width(), container.height(), |
181 0, gl_format, gl_type, container->data()); | 181 0, gl_format, gl_type, container.data()); |
182 | 182 |
183 scoped_ptr<OpenGlesTextureData> data(new OpenGlesTextureData(gl_)); | 183 scoped_ptr<OpenGlesTextureData> data(new OpenGlesTextureData(gl_)); |
184 data->SetTexture(texture); | 184 data->SetTexture(texture); |
185 data->set_has_alpha(ImageFormatUsesAlpha(container->format())); | 185 data->set_has_alpha(ImageFormatUsesAlpha(container.format())); |
186 actor->set_texture_data(data.release()); | 186 actor->set_texture_data(data.release()); |
187 } | 187 } |
188 | 188 |
189 void OpenGlesDrawVisitor::VisitStage(RealCompositor::StageActor* actor) { | 189 void OpenGlesDrawVisitor::VisitStage(RealCompositor::StageActor* actor) { |
190 if (!actor->IsVisible()) | 190 if (!actor->IsVisible()) |
191 return; | 191 return; |
192 | 192 |
193 if (actor->stage_color_changed()) { | 193 if (actor->stage_color_changed()) { |
194 const Compositor::Color& color = actor->stage_color(); | 194 const Compositor::Color& color = actor->stage_color(); |
195 gl_->ClearColor(color.red, color.green, color.blue, 1.f); | 195 gl_->ClearColor(color.red, color.green, color.blue, 1.f); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 gl_->EglPostSubBufferNV(egl_display_, egl_surface_, | 253 gl_->EglPostSubBufferNV(egl_display_, egl_surface_, |
254 damaged_region_.x, | 254 damaged_region_.x, |
255 damaged_region_.y, | 255 damaged_region_.y, |
256 damaged_region_.width, | 256 damaged_region_.width, |
257 damaged_region_.height); | 257 damaged_region_.height); |
258 } else { | 258 } else { |
259 gl_->EglSwapBuffers(egl_display_, egl_surface_); | 259 gl_->EglSwapBuffers(egl_display_, egl_surface_); |
260 } | 260 } |
261 } | 261 } |
262 | 262 |
263 void OpenGlesDrawVisitor::CreateTextureData( | 263 void OpenGlesDrawVisitor::VisitContainer( |
264 RealCompositor::TexturePixmapActor* actor) const { | 264 RealCompositor::ContainerActor* actor) { |
265 OpenGlesEglImageData image_data(gl_); | 265 if (!actor->IsVisible()) |
266 | |
267 if (!image_data.Bind(actor)) | |
268 return; | 266 return; |
269 | 267 |
270 scoped_ptr<OpenGlesTextureData> texture(new OpenGlesTextureData(gl_)); | 268 LOG(INFO) << "Visit container: " << actor->name(); |
271 image_data.BindTexture(texture.get(), !actor->pixmap_is_opaque()); | 269 |
272 actor->set_texture_data(texture.release()); | 270 const float original_opacity = ancestor_opacity_; |
| 271 ancestor_opacity_ *= actor->opacity(); |
| 272 |
| 273 // Back to front rendering |
| 274 const RealCompositor::ActorVector children = actor->GetChildren(); |
| 275 for (RealCompositor::ActorVector::const_reverse_iterator i = |
| 276 children.rbegin(); i != children.rend(); ++i) { |
| 277 // TODO move this down into the Visit* functions |
| 278 if ((*i)->is_opaque() && (*i)->opacity() * ancestor_opacity_ > 0.999) |
| 279 gl_->Disable(GL_BLEND); |
| 280 else |
| 281 gl_->Enable(GL_BLEND); |
| 282 (*i)->Accept(this); |
| 283 } |
| 284 |
| 285 // Reset opacity. |
| 286 ancestor_opacity_ = original_opacity; |
273 } | 287 } |
274 | 288 |
275 void OpenGlesDrawVisitor::VisitImage(RealCompositor::ImageActor* actor) { | 289 void OpenGlesDrawVisitor::VisitImage(RealCompositor::ImageActor* actor) { |
276 VisitQuad(actor); | 290 VisitQuad(actor); |
277 } | 291 } |
278 | 292 |
279 void OpenGlesDrawVisitor::VisitTexturePixmap( | 293 void OpenGlesDrawVisitor::VisitTexturePixmap( |
280 RealCompositor::TexturePixmapActor* actor) { | 294 RealCompositor::TexturePixmapActor* actor) { |
281 if (!actor->IsVisible()) | 295 if (!actor->IsVisible()) |
282 return; | 296 return; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 PopScissorRect(); | 450 PopScissorRect(); |
437 } else { | 451 } else { |
438 // The quad vertices must start at index zero to line up with the non-VBO | 452 // The quad vertices must start at index zero to line up with the non-VBO |
439 // colors array indices. If they're moved, the colors array needs to be | 453 // colors array indices. If they're moved, the colors array needs to be |
440 // resized and shifted accordingly. | 454 // resized and shifted accordingly. |
441 DCHECK(quad_vertices_index_ == 0); | 455 DCHECK(quad_vertices_index_ == 0); |
442 gl_->DrawArrays(GL_TRIANGLE_STRIP, quad_vertices_index_, 4); | 456 gl_->DrawArrays(GL_TRIANGLE_STRIP, quad_vertices_index_, 4); |
443 } | 457 } |
444 } | 458 } |
445 | 459 |
| 460 void OpenGlesDrawVisitor::CreateTextureData( |
| 461 RealCompositor::TexturePixmapActor* actor) const { |
| 462 OpenGlesEglImageData image_data(gl_); |
| 463 |
| 464 if (!image_data.Bind(actor)) |
| 465 return; |
| 466 |
| 467 scoped_ptr<OpenGlesTextureData> texture(new OpenGlesTextureData(gl_)); |
| 468 image_data.BindTexture(texture.get(), !actor->pixmap_is_opaque()); |
| 469 actor->set_texture_data(texture.release()); |
| 470 } |
| 471 |
446 void OpenGlesDrawVisitor::PushScissorRect(const Rect& scissor) { | 472 void OpenGlesDrawVisitor::PushScissorRect(const Rect& scissor) { |
447 if (scissor_stack_.empty()) { | 473 if (scissor_stack_.empty()) { |
448 scissor_stack_.push_back(scissor); | 474 scissor_stack_.push_back(scissor); |
449 gl_->Enable(GL_SCISSOR_TEST); | 475 gl_->Enable(GL_SCISSOR_TEST); |
450 gl_->Scissor(scissor.x, scissor.y, | 476 gl_->Scissor(scissor.x, scissor.y, |
451 scissor.width, scissor.height); | 477 scissor.width, scissor.height); |
452 } else { | 478 } else { |
453 Rect new_scissor = scissor; | 479 Rect new_scissor = scissor; |
454 new_scissor.intersect(scissor_stack_.back()); | 480 new_scissor.intersect(scissor_stack_.back()); |
455 scissor_stack_.push_back(new_scissor); | 481 scissor_stack_.push_back(new_scissor); |
456 gl_->Scissor(new_scissor.x, new_scissor.y, | 482 gl_->Scissor(new_scissor.x, new_scissor.y, |
457 new_scissor.width, new_scissor.height); | 483 new_scissor.width, new_scissor.height); |
458 } | 484 } |
459 } | 485 } |
460 | 486 |
461 void OpenGlesDrawVisitor::PopScissorRect() { | 487 void OpenGlesDrawVisitor::PopScissorRect() { |
462 DCHECK(!scissor_stack_.empty()); | 488 DCHECK(!scissor_stack_.empty()); |
463 scissor_stack_.pop_back(); | 489 scissor_stack_.pop_back(); |
464 | 490 |
465 if (scissor_stack_.empty()) { | 491 if (scissor_stack_.empty()) { |
466 gl_->Disable(GL_SCISSOR_TEST); | 492 gl_->Disable(GL_SCISSOR_TEST); |
467 } else { | 493 } else { |
468 const Rect& new_scissor = scissor_stack_.back(); | 494 const Rect& new_scissor = scissor_stack_.back(); |
469 gl_->Scissor(new_scissor.x, new_scissor.y, | 495 gl_->Scissor(new_scissor.x, new_scissor.y, |
470 new_scissor.width, new_scissor.height); | 496 new_scissor.width, new_scissor.height); |
471 } | 497 } |
472 } | 498 } |
473 | 499 |
474 void OpenGlesDrawVisitor::VisitContainer( | |
475 RealCompositor::ContainerActor* actor) { | |
476 if (!actor->IsVisible()) | |
477 return; | |
478 | |
479 LOG(INFO) << "Visit container: " << actor->name(); | |
480 | |
481 const float original_opacity = ancestor_opacity_; | |
482 ancestor_opacity_ *= actor->opacity(); | |
483 | |
484 // Back to front rendering | |
485 const RealCompositor::ActorVector children = actor->GetChildren(); | |
486 for (RealCompositor::ActorVector::const_reverse_iterator i = | |
487 children.rbegin(); i != children.rend(); ++i) { | |
488 // TODO move this down into the Visit* functions | |
489 if ((*i)->is_opaque() && (*i)->opacity() * ancestor_opacity_ > 0.999) | |
490 gl_->Disable(GL_BLEND); | |
491 else | |
492 gl_->Enable(GL_BLEND); | |
493 (*i)->Accept(this); | |
494 } | |
495 | |
496 // Reset opacity. | |
497 ancestor_opacity_ = original_opacity; | |
498 } | |
499 | |
500 OpenGlesTextureData::OpenGlesTextureData(Gles2Interface* gl) | 500 OpenGlesTextureData::OpenGlesTextureData(Gles2Interface* gl) |
501 : gl_(gl) {} | 501 : gl_(gl) {} |
502 | 502 |
503 OpenGlesTextureData::~OpenGlesTextureData() { | 503 OpenGlesTextureData::~OpenGlesTextureData() { |
504 gl_->DeleteTextures(1, texture_ptr()); | 504 gl_->DeleteTextures(1, texture_ptr()); |
505 } | 505 } |
506 | 506 |
507 void OpenGlesTextureData::SetTexture(GLuint texture) { | 507 void OpenGlesTextureData::SetTexture(GLuint texture) { |
508 gl_->DeleteTextures(1, texture_ptr()); | 508 gl_->DeleteTextures(1, texture_ptr()); |
509 set_texture(texture); | 509 set_texture(texture); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 558 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
559 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 559 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
560 gl_->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, | 560 gl_->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, |
561 static_cast<GLeglImageOES>(egl_image_)); | 561 static_cast<GLeglImageOES>(egl_image_)); |
562 | 562 |
563 texture_data->SetTexture(texture); | 563 texture_data->SetTexture(texture); |
564 texture_data->set_has_alpha(has_alpha); | 564 texture_data->set_has_alpha(has_alpha); |
565 } | 565 } |
566 | 566 |
567 } // namespace window_manager | 567 } // namespace window_manager |
OLD | NEW |