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 |