| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/display_compositor/buffer_queue.h" | 5 #include "components/display_compositor/buffer_queue.h" |
| 6 | 6 |
| 7 #include "base/containers/adapters.h" | 7 #include "base/containers/adapters.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 #include "components/display_compositor/gl_helper.h" | 10 #include "components/display_compositor/gl_helper.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 | 53 |
| 54 void BufferQueue::BindFramebuffer() { | 54 void BufferQueue::BindFramebuffer() { |
| 55 gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_); | 55 gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_); |
| 56 | 56 |
| 57 if (!current_surface_) | 57 if (!current_surface_) |
| 58 current_surface_ = GetNextSurface(); | 58 current_surface_ = GetNextSurface(); |
| 59 | 59 |
| 60 if (current_surface_) { | 60 if (current_surface_) { |
| 61 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 61 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 62 texture_target_, current_surface_->texture, 0); | 62 texture_target_, current_surface_->texture, 0); |
| 63 if (current_surface_->stencil) { |
| 64 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, |
| 65 GL_RENDERBUFFER, current_surface_->stencil); |
| 66 } |
| 63 } | 67 } |
| 64 } | 68 } |
| 65 | 69 |
| 66 void BufferQueue::CopyBufferDamage(int texture, | 70 void BufferQueue::CopyBufferDamage(int texture, |
| 67 int source_texture, | 71 int source_texture, |
| 68 const gfx::Rect& new_damage, | 72 const gfx::Rect& new_damage, |
| 69 const gfx::Rect& old_damage) { | 73 const gfx::Rect& old_damage) { |
| 70 gl_helper_->CopySubBufferDamage(texture_target_, texture, source_texture, | 74 gl_helper_->CopySubBufferDamage(texture_target_, texture, source_texture, |
| 71 SkRegion(gfx::RectToSkIRect(new_damage)), | 75 SkRegion(gfx::RectToSkIRect(new_damage)), |
| 72 SkRegion(gfx::RectToSkIRect(old_damage))); | 76 SkRegion(gfx::RectToSkIRect(old_damage))); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 112 } |
| 109 UpdateBufferDamage(damage); | 113 UpdateBufferDamage(damage); |
| 110 in_flight_surfaces_.push_back(std::move(current_surface_)); | 114 in_flight_surfaces_.push_back(std::move(current_surface_)); |
| 111 // Some things reset the framebuffer (CopySubBufferDamage, some GLRenderer | 115 // Some things reset the framebuffer (CopySubBufferDamage, some GLRenderer |
| 112 // paths), so ensure we restore it here. | 116 // paths), so ensure we restore it here. |
| 113 gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_); | 117 gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_); |
| 114 } | 118 } |
| 115 | 119 |
| 116 void BufferQueue::Reshape(const gfx::Size& size, | 120 void BufferQueue::Reshape(const gfx::Size& size, |
| 117 float scale_factor, | 121 float scale_factor, |
| 118 const gfx::ColorSpace& color_space) { | 122 const gfx::ColorSpace& color_space, |
| 119 if (size == size_ && color_space == color_space_) | 123 bool use_stencil) { |
| 124 if (size == size_ && color_space == color_space_ && |
| 125 use_stencil == use_stencil_) |
| 120 return; | 126 return; |
| 121 #if !defined(OS_MACOSX) | 127 #if !defined(OS_MACOSX) |
| 122 // TODO(ccameron): This assert is being hit on Mac try jobs. Determine if that | 128 // TODO(ccameron): This assert is being hit on Mac try jobs. Determine if that |
| 123 // is cause for concern or if it is benign. | 129 // is cause for concern or if it is benign. |
| 124 // http://crbug.com/524624 | 130 // http://crbug.com/524624 |
| 125 DCHECK(!current_surface_); | 131 DCHECK(!current_surface_); |
| 126 #endif | 132 #endif |
| 127 size_ = size; | 133 size_ = size; |
| 128 color_space_ = color_space; | 134 color_space_ = color_space; |
| 135 use_stencil_ = use_stencil; |
| 129 | 136 |
| 130 // TODO: add stencil buffer when needed. | |
| 131 gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_); | 137 gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_); |
| 132 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 138 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 133 texture_target_, 0, 0); | 139 texture_target_, 0, 0); |
| 140 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, |
| 141 GL_RENDERBUFFER, 0); |
| 134 | 142 |
| 135 FreeAllSurfaces(); | 143 FreeAllSurfaces(); |
| 136 } | 144 } |
| 137 | 145 |
| 138 void BufferQueue::RecreateBuffers() { | 146 void BufferQueue::RecreateBuffers() { |
| 139 // We need to recreate the buffers, for whatever reason the old ones are not | 147 // We need to recreate the buffers, for whatever reason the old ones are not |
| 140 // presentable on the device anymore. | 148 // presentable on the device anymore. |
| 141 // Unused buffers can be freed directly, they will be re-allocated as needed. | 149 // Unused buffers can be freed directly, they will be re-allocated as needed. |
| 142 // Any in flight, current or displayed surface must be replaced. | 150 // Any in flight, current or displayed surface must be replaced. |
| 143 available_surfaces_.clear(); | 151 available_surfaces_.clear(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 } | 201 } |
| 194 | 202 |
| 195 void BufferQueue::FreeSurfaceResources(AllocatedSurface* surface) { | 203 void BufferQueue::FreeSurfaceResources(AllocatedSurface* surface) { |
| 196 if (!surface->texture) | 204 if (!surface->texture) |
| 197 return; | 205 return; |
| 198 | 206 |
| 199 gl_->BindTexture(texture_target_, surface->texture); | 207 gl_->BindTexture(texture_target_, surface->texture); |
| 200 gl_->ReleaseTexImage2DCHROMIUM(texture_target_, surface->image); | 208 gl_->ReleaseTexImage2DCHROMIUM(texture_target_, surface->image); |
| 201 gl_->DeleteTextures(1, &surface->texture); | 209 gl_->DeleteTextures(1, &surface->texture); |
| 202 gl_->DestroyImageCHROMIUM(surface->image); | 210 gl_->DestroyImageCHROMIUM(surface->image); |
| 211 if (surface->stencil) |
| 212 gl_->DeleteRenderbuffers(1, &surface->stencil); |
| 203 surface->buffer.reset(); | 213 surface->buffer.reset(); |
| 204 allocated_count_--; | 214 allocated_count_--; |
| 205 } | 215 } |
| 206 | 216 |
| 207 std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface() { | 217 std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface() { |
| 208 if (!available_surfaces_.empty()) { | 218 if (!available_surfaces_.empty()) { |
| 209 std::unique_ptr<AllocatedSurface> surface = | 219 std::unique_ptr<AllocatedSurface> surface = |
| 210 std::move(available_surfaces_.back()); | 220 std::move(available_surfaces_.back()); |
| 211 available_surfaces_.pop_back(); | 221 available_surfaces_.pop_back(); |
| 212 return surface; | 222 return surface; |
| 213 } | 223 } |
| 214 | 224 |
| 215 GLuint texture; | 225 GLuint texture; |
| 216 gl_->GenTextures(1, &texture); | 226 gl_->GenTextures(1, &texture); |
| 217 | 227 |
| 228 GLuint stencil = 0; |
| 229 if (use_stencil_) { |
| 230 gl_->GenRenderbuffers(1, &stencil); |
| 231 gl_->BindRenderbuffer(GL_RENDERBUFFER, stencil); |
| 232 gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, size_.width(), |
| 233 size_.height()); |
| 234 gl_->BindRenderbuffer(GL_RENDERBUFFER, 0); |
| 235 } |
| 236 |
| 218 // We don't want to allow anything more than triple buffering. | 237 // We don't want to allow anything more than triple buffering. |
| 219 DCHECK_LT(allocated_count_, 4U); | 238 DCHECK_LT(allocated_count_, 4U); |
| 220 std::unique_ptr<gfx::GpuMemoryBuffer> buffer( | 239 std::unique_ptr<gfx::GpuMemoryBuffer> buffer( |
| 221 gpu_memory_buffer_manager_->CreateGpuMemoryBuffer( | 240 gpu_memory_buffer_manager_->CreateGpuMemoryBuffer( |
| 222 size_, format_, gfx::BufferUsage::SCANOUT, surface_handle_)); | 241 size_, format_, gfx::BufferUsage::SCANOUT, surface_handle_)); |
| 223 if (!buffer.get()) { | 242 if (!buffer.get()) { |
| 224 gl_->DeleteTextures(1, &texture); | 243 gl_->DeleteTextures(1, &texture); |
| 225 DLOG(ERROR) << "Failed to allocate GPU memory buffer"; | 244 DLOG(ERROR) << "Failed to allocate GPU memory buffer"; |
| 226 return nullptr; | 245 return nullptr; |
| 227 } | 246 } |
| 228 buffer->SetColorSpaceForScanout(color_space_); | 247 buffer->SetColorSpaceForScanout(color_space_); |
| 229 | 248 |
| 230 uint32_t id = | 249 uint32_t id = |
| 231 gl_->CreateImageCHROMIUM(buffer->AsClientBuffer(), size_.width(), | 250 gl_->CreateImageCHROMIUM(buffer->AsClientBuffer(), size_.width(), |
| 232 size_.height(), internal_format_); | 251 size_.height(), internal_format_); |
| 233 if (!id) { | 252 if (!id) { |
| 234 LOG(ERROR) << "Failed to allocate backing image surface"; | 253 LOG(ERROR) << "Failed to allocate backing image surface"; |
| 235 gl_->DeleteTextures(1, &texture); | 254 gl_->DeleteTextures(1, &texture); |
| 236 return nullptr; | 255 return nullptr; |
| 237 } | 256 } |
| 238 | 257 |
| 239 allocated_count_++; | 258 allocated_count_++; |
| 240 gl_->BindTexture(texture_target_, texture); | 259 gl_->BindTexture(texture_target_, texture); |
| 241 gl_->BindTexImage2DCHROMIUM(texture_target_, id); | 260 gl_->BindTexImage2DCHROMIUM(texture_target_, id); |
| 242 return base::MakeUnique<AllocatedSurface>(this, std::move(buffer), texture, | 261 return base::MakeUnique<AllocatedSurface>(this, std::move(buffer), texture, |
| 243 id, gfx::Rect(size_)); | 262 id, stencil, gfx::Rect(size_)); |
| 244 } | 263 } |
| 245 | 264 |
| 246 BufferQueue::AllocatedSurface::AllocatedSurface( | 265 BufferQueue::AllocatedSurface::AllocatedSurface( |
| 247 BufferQueue* buffer_queue, | 266 BufferQueue* buffer_queue, |
| 248 std::unique_ptr<gfx::GpuMemoryBuffer> buffer, | 267 std::unique_ptr<gfx::GpuMemoryBuffer> buffer, |
| 249 uint32_t texture, | 268 uint32_t texture, |
| 250 uint32_t image, | 269 uint32_t image, |
| 270 uint32_t stencil, |
| 251 const gfx::Rect& rect) | 271 const gfx::Rect& rect) |
| 252 : buffer_queue(buffer_queue), | 272 : buffer_queue(buffer_queue), |
| 253 buffer(buffer.release()), | 273 buffer(buffer.release()), |
| 254 texture(texture), | 274 texture(texture), |
| 255 image(image), | 275 image(image), |
| 276 stencil(stencil), |
| 256 damage(rect) {} | 277 damage(rect) {} |
| 257 | 278 |
| 258 BufferQueue::AllocatedSurface::~AllocatedSurface() { | 279 BufferQueue::AllocatedSurface::~AllocatedSurface() { |
| 259 buffer_queue->FreeSurfaceResources(this); | 280 buffer_queue->FreeSurfaceResources(this); |
| 260 } | 281 } |
| 261 | 282 |
| 262 } // namespace display_compositor | 283 } // namespace display_compositor |
| OLD | NEW |