| 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 "content/common/gpu/image_transport_surface_fbo_mac.h" | 5 #include "content/common/gpu/image_transport_surface_fbo_mac.h" |
| 6 | 6 |
| 7 #include "content/common/gpu/gpu_messages.h" | 7 #include "content/common/gpu/gpu_messages.h" |
| 8 #include "content/common/gpu/image_transport_surface_calayer_mac.h" | 8 #include "content/common/gpu/image_transport_surface_calayer_mac.h" |
| 9 #include "content/common/gpu/image_transport_surface_iosurface_mac.h" | 9 #include "content/common/gpu/image_transport_surface_iosurface_mac.h" |
| 10 #include "ui/base/cocoa/remote_layer_api.h" | 10 #include "ui/base/cocoa/remote_layer_api.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 bool ImageTransportSurfaceFBO::IsOffscreen() { | 68 bool ImageTransportSurfaceFBO::IsOffscreen() { |
| 69 return false; | 69 return false; |
| 70 } | 70 } |
| 71 | 71 |
| 72 bool ImageTransportSurfaceFBO::OnMakeCurrent(gfx::GLContext* context) { | 72 bool ImageTransportSurfaceFBO::OnMakeCurrent(gfx::GLContext* context) { |
| 73 context_ = context; | 73 context_ = context; |
| 74 | 74 |
| 75 if (made_current_) | 75 if (made_current_) |
| 76 return true; | 76 return true; |
| 77 | 77 |
| 78 OnResize(gfx::Size(1, 1), 1.f); | 78 AllocateOrResizeFramebuffer(gfx::Size(1, 1), 1.f); |
| 79 | 79 |
| 80 made_current_ = true; | 80 made_current_ = true; |
| 81 return true; | 81 return true; |
| 82 } | 82 } |
| 83 | 83 |
| 84 unsigned int ImageTransportSurfaceFBO::GetBackingFrameBufferObject() { | 84 unsigned int ImageTransportSurfaceFBO::GetBackingFrameBufferObject() { |
| 85 return fbo_id_; | 85 return fbo_id_; |
| 86 } | 86 } |
| 87 | 87 |
| 88 bool ImageTransportSurfaceFBO::SetBackbufferAllocation(bool allocation) { | 88 bool ImageTransportSurfaceFBO::SetBackbufferAllocation(bool allocation) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 103 } | 103 } |
| 104 | 104 |
| 105 void ImageTransportSurfaceFBO::AdjustBufferAllocation() { | 105 void ImageTransportSurfaceFBO::AdjustBufferAllocation() { |
| 106 // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is | 106 // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is |
| 107 // free'd when both the browser and gpu processes have Unref'd the IOSurface. | 107 // free'd when both the browser and gpu processes have Unref'd the IOSurface. |
| 108 if (!backbuffer_suggested_allocation_ && | 108 if (!backbuffer_suggested_allocation_ && |
| 109 !frontbuffer_suggested_allocation_ && | 109 !frontbuffer_suggested_allocation_ && |
| 110 has_complete_framebuffer_) { | 110 has_complete_framebuffer_) { |
| 111 DestroyFramebuffer(); | 111 DestroyFramebuffer(); |
| 112 } else if (backbuffer_suggested_allocation_ && !has_complete_framebuffer_) { | 112 } else if (backbuffer_suggested_allocation_ && !has_complete_framebuffer_) { |
| 113 CreateFramebuffer(); | 113 AllocateOrResizeFramebuffer(pixel_size_, scale_factor_); |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 | 116 |
| 117 bool ImageTransportSurfaceFBO::SwapBuffers() { | 117 bool ImageTransportSurfaceFBO::SwapBuffers() { |
| 118 DCHECK(backbuffer_suggested_allocation_); | 118 DCHECK(backbuffer_suggested_allocation_); |
| 119 if (!frontbuffer_suggested_allocation_) | 119 if (!frontbuffer_suggested_allocation_) |
| 120 return true; | 120 return true; |
| 121 glFlush(); | 121 glFlush(); |
| 122 | 122 |
| 123 // It is the responsibility of the storage provider to send the swap IPC. | 123 // It is the responsibility of the storage provider to send the swap IPC. |
| 124 is_swap_buffers_send_pending_ = true; | 124 is_swap_buffers_send_pending_ = true; |
| 125 storage_provider_->SwapBuffers(size_, scale_factor_); | 125 storage_provider_->SwapBuffers(pixel_size_, scale_factor_); |
| 126 return true; | 126 return true; |
| 127 } | 127 } |
| 128 | 128 |
| 129 void ImageTransportSurfaceFBO::SendSwapBuffers(uint64 surface_handle, | 129 void ImageTransportSurfaceFBO::SendSwapBuffers(uint64 surface_handle, |
| 130 const gfx::Size pixel_size, | 130 const gfx::Size pixel_size, |
| 131 float scale_factor) { | 131 float scale_factor) { |
| 132 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | 132 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| 133 params.surface_handle = surface_handle; | 133 params.surface_handle = surface_handle; |
| 134 params.size = pixel_size; | 134 params.size = pixel_size; |
| 135 params.scale_factor = scale_factor; | 135 params.scale_factor = scale_factor; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 148 // Mac does not support sub-buffer swaps. | 148 // Mac does not support sub-buffer swaps. |
| 149 NOTREACHED(); | 149 NOTREACHED(); |
| 150 return false; | 150 return false; |
| 151 } | 151 } |
| 152 | 152 |
| 153 bool ImageTransportSurfaceFBO::SupportsPostSubBuffer() { | 153 bool ImageTransportSurfaceFBO::SupportsPostSubBuffer() { |
| 154 return true; | 154 return true; |
| 155 } | 155 } |
| 156 | 156 |
| 157 gfx::Size ImageTransportSurfaceFBO::GetSize() { | 157 gfx::Size ImageTransportSurfaceFBO::GetSize() { |
| 158 return size_; | 158 return pixel_size_; |
| 159 } | 159 } |
| 160 | 160 |
| 161 void* ImageTransportSurfaceFBO::GetHandle() { | 161 void* ImageTransportSurfaceFBO::GetHandle() { |
| 162 return NULL; | 162 return NULL; |
| 163 } | 163 } |
| 164 | 164 |
| 165 void* ImageTransportSurfaceFBO::GetDisplay() { | 165 void* ImageTransportSurfaceFBO::GetDisplay() { |
| 166 return NULL; | 166 return NULL; |
| 167 } | 167 } |
| 168 | 168 |
| 169 void ImageTransportSurfaceFBO::OnBufferPresented( | 169 void ImageTransportSurfaceFBO::OnBufferPresented( |
| 170 const AcceleratedSurfaceMsg_BufferPresented_Params& params) { | 170 const AcceleratedSurfaceMsg_BufferPresented_Params& params) { |
| 171 SetRendererID(params.renderer_id); | 171 SetRendererID(params.renderer_id); |
| 172 storage_provider_->SwapBuffersAckedByBrowser(params.disable_throttling); | 172 storage_provider_->SwapBuffersAckedByBrowser(params.disable_throttling); |
| 173 } | 173 } |
| 174 | 174 |
| 175 void ImageTransportSurfaceFBO::OnResize(gfx::Size size, | 175 void ImageTransportSurfaceFBO::OnResize(gfx::Size pixel_size, |
| 176 float scale_factor) { | 176 float scale_factor) { |
| 177 TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::OnResize", | 177 TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::OnResize", |
| 178 "old_width", size_.width(), "new_width", size.width()); | 178 "old_size", pixel_size_.ToString(), |
| 179 "new_size", pixel_size.ToString()); |
| 179 // Caching |context_| from OnMakeCurrent. It should still be current. | 180 // Caching |context_| from OnMakeCurrent. It should still be current. |
| 180 DCHECK(context_->IsCurrent(this)); | 181 DCHECK(context_->IsCurrent(this)); |
| 181 | 182 |
| 182 size_ = size; | 183 AllocateOrResizeFramebuffer(pixel_size, scale_factor); |
| 183 scale_factor_ = scale_factor; | |
| 184 | |
| 185 CreateFramebuffer(); | |
| 186 } | 184 } |
| 187 | 185 |
| 188 void ImageTransportSurfaceFBO::SetLatencyInfo( | 186 void ImageTransportSurfaceFBO::SetLatencyInfo( |
| 189 const std::vector<ui::LatencyInfo>& latency_info) { | 187 const std::vector<ui::LatencyInfo>& latency_info) { |
| 190 for (size_t i = 0; i < latency_info.size(); i++) | 188 for (size_t i = 0; i < latency_info.size(); i++) |
| 191 latency_info_.push_back(latency_info[i]); | 189 latency_info_.push_back(latency_info[i]); |
| 192 } | 190 } |
| 193 | 191 |
| 194 void ImageTransportSurfaceFBO::WakeUpGpu() { | 192 void ImageTransportSurfaceFBO::WakeUpGpu() { |
| 195 NOTIMPLEMENTED(); | 193 NOTIMPLEMENTED(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 222 if (depth_stencil_renderbuffer_id_) { | 220 if (depth_stencil_renderbuffer_id_) { |
| 223 glDeleteRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_); | 221 glDeleteRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_); |
| 224 depth_stencil_renderbuffer_id_ = 0; | 222 depth_stencil_renderbuffer_id_ = 0; |
| 225 } | 223 } |
| 226 | 224 |
| 227 storage_provider_->FreeColorBufferStorage(); | 225 storage_provider_->FreeColorBufferStorage(); |
| 228 | 226 |
| 229 has_complete_framebuffer_ = false; | 227 has_complete_framebuffer_ = false; |
| 230 } | 228 } |
| 231 | 229 |
| 232 void ImageTransportSurfaceFBO::CreateFramebuffer() { | 230 void ImageTransportSurfaceFBO::AllocateOrResizeFramebuffer( |
| 233 gfx::Size new_rounded_size = storage_provider_->GetRoundedSize(size_); | 231 const gfx::Size& new_pixel_size, float new_scale_factor) { |
| 232 gfx::Size new_rounded_pixel_size = |
| 233 storage_provider_->GetRoundedSize(new_pixel_size); |
| 234 | 234 |
| 235 // Only recreate surface when the rounded up size has changed. | 235 // Only recreate the surface's storage when the rounded up size has changed, |
| 236 if (has_complete_framebuffer_ && new_rounded_size == rounded_size_) | 236 // or the scale factor has changed. |
| 237 bool needs_new_storage = |
| 238 !has_complete_framebuffer_ || |
| 239 new_rounded_pixel_size != rounded_pixel_size_ || |
| 240 new_scale_factor != scale_factor_; |
| 241 |
| 242 // Save the new storage parameters. |
| 243 pixel_size_ = new_pixel_size; |
| 244 rounded_pixel_size_ = new_rounded_pixel_size; |
| 245 scale_factor_ = new_scale_factor; |
| 246 |
| 247 if (!needs_new_storage) |
| 237 return; | 248 return; |
| 238 | 249 |
| 239 TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::CreateFramebuffer", | 250 TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::AllocateOrResizeFramebuffer", |
| 240 "width", new_rounded_size.width(), | 251 "width", new_rounded_pixel_size.width(), |
| 241 "height", new_rounded_size.height()); | 252 "height", new_rounded_pixel_size.height()); |
| 242 | |
| 243 rounded_size_ = new_rounded_size; | |
| 244 | 253 |
| 245 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on | 254 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on |
| 246 // Mac OS X and is required for IOSurface interoperability. | 255 // Mac OS X and is required for IOSurface interoperability. |
| 247 GLint previous_texture_id = 0; | 256 GLint previous_texture_id = 0; |
| 248 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); | 257 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); |
| 249 | 258 |
| 250 // Free the old IO Surface first to reduce memory fragmentation. | 259 // Free the old IO Surface first to reduce memory fragmentation. |
| 251 DestroyFramebuffer(); | 260 DestroyFramebuffer(); |
| 252 | 261 |
| 253 glGenFramebuffersEXT(1, &fbo_id_); | 262 glGenFramebuffersEXT(1, &fbo_id_); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 279 bool has_packed_depth_stencil = | 288 bool has_packed_depth_stencil = |
| 280 GLSurface::ExtensionsContain( | 289 GLSurface::ExtensionsContain( |
| 281 reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)), | 290 reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)), |
| 282 "GL_EXT_packed_depth_stencil"); | 291 "GL_EXT_packed_depth_stencil"); |
| 283 | 292 |
| 284 if (has_packed_depth_stencil) { | 293 if (has_packed_depth_stencil) { |
| 285 glGenRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_); | 294 glGenRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_); |
| 286 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, | 295 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, |
| 287 depth_stencil_renderbuffer_id_); | 296 depth_stencil_renderbuffer_id_); |
| 288 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, | 297 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, |
| 289 rounded_size_.width(), rounded_size_.height()); | 298 rounded_pixel_size_.width(), |
| 299 rounded_pixel_size_.height()); |
| 290 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | 300 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, |
| 291 GL_STENCIL_ATTACHMENT_EXT, | 301 GL_STENCIL_ATTACHMENT_EXT, |
| 292 GL_RENDERBUFFER_EXT, | 302 GL_RENDERBUFFER_EXT, |
| 293 depth_stencil_renderbuffer_id_); | 303 depth_stencil_renderbuffer_id_); |
| 294 } | 304 } |
| 295 | 305 |
| 296 // If we asked for stencil but the extension isn't present, | 306 // If we asked for stencil but the extension isn't present, |
| 297 // it's OK to silently fail; subsequent code will/must check | 307 // it's OK to silently fail; subsequent code will/must check |
| 298 // for the presence of a stencil buffer before attempting to | 308 // for the presence of a stencil buffer before attempting to |
| 299 // do stencil-based operations. | 309 // do stencil-based operations. |
| 300 } | 310 } |
| 301 | 311 |
| 302 bool allocated_color_buffer = storage_provider_->AllocateColorBufferStorage( | 312 bool allocated_color_buffer = storage_provider_->AllocateColorBufferStorage( |
| 303 static_cast<CGLContextObj>(context_->GetHandle()), texture_id_, | 313 static_cast<CGLContextObj>(context_->GetHandle()), texture_id_, |
| 304 rounded_size_, scale_factor_); | 314 rounded_pixel_size_, scale_factor_); |
| 305 if (!allocated_color_buffer) { | 315 if (!allocated_color_buffer) { |
| 306 DLOG(ERROR) << "Failed to allocate color buffer storage."; | 316 DLOG(ERROR) << "Failed to allocate color buffer storage."; |
| 307 DestroyFramebuffer(); | 317 DestroyFramebuffer(); |
| 308 return; | 318 return; |
| 309 } | 319 } |
| 310 | 320 |
| 311 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); | 321 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); |
| 312 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { | 322 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { |
| 313 DLOG(ERROR) << "Framebuffer was incomplete: " << status; | 323 DLOG(ERROR) << "Framebuffer was incomplete: " << status; |
| 314 DestroyFramebuffer(); | 324 DestroyFramebuffer(); |
| 315 return; | 325 return; |
| 316 } | 326 } |
| 317 | 327 |
| 318 has_complete_framebuffer_ = true; | 328 has_complete_framebuffer_ = true; |
| 319 | 329 |
| 320 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, previous_texture_id); | 330 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, previous_texture_id); |
| 321 // The FBO remains bound for this GL context. | 331 // The FBO remains bound for this GL context. |
| 322 } | 332 } |
| 323 | 333 |
| 324 } // namespace content | 334 } // namespace content |
| OLD | NEW |