Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: ui/gfx/surface/accelerated_surface_mac.cc

Issue 7191025: Fixed warning from Core Graphics related to zero-width or zero-height (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gfx/surface/accelerated_surface_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ui/gfx/surface/accelerated_surface_mac.h" 5 #include "ui/gfx/surface/accelerated_surface_mac.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/mac/scoped_cftyperef.h" 8 #include "base/mac/scoped_cftyperef.h"
9 #include "ui/gfx/gl/gl_bindings.h" 9 #include "ui/gfx/gl/gl_bindings.h"
10 #include "ui/gfx/gl/gl_implementation.h" 10 #include "ui/gfx/gl/gl_implementation.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 // rendering results consumed by the AcceleratedSurface. 87 // rendering results consumed by the AcceleratedSurface.
88 // Need to save and restore OpenGL state around this call. 88 // Need to save and restore OpenGL state around this call.
89 GLint current_texture = 0; 89 GLint current_texture = 0;
90 GLenum target_binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; 90 GLenum target_binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
91 GLenum target = GL_TEXTURE_RECTANGLE_ARB; 91 GLenum target = GL_TEXTURE_RECTANGLE_ARB;
92 glGetIntegerv(target_binding, &current_texture); 92 glGetIntegerv(target_binding, &current_texture);
93 glBindTexture(target, texture_); 93 glBindTexture(target, texture_);
94 glCopyTexSubImage2D(target, 0, 94 glCopyTexSubImage2D(target, 0,
95 0, 0, 95 0, 0,
96 0, 0, 96 0, 0,
97 surface_size_.width(), surface_size_.height()); 97 real_surface_size_.width(),
98 real_surface_size_.height());
98 glBindTexture(target, current_texture); 99 glBindTexture(target, current_texture);
99 // This flush is absolutely essential -- it guarantees that the 100 // This flush is absolutely essential -- it guarantees that the
100 // rendering results are seen by the other process. 101 // rendering results are seen by the other process.
101 glFlush(); 102 glFlush();
102 } 103 }
103 } else if (transport_dib_.get() != NULL) { 104 } else if (transport_dib_.get() != NULL) {
104 // Pre-Mac OS X 10.6, fetch the rendered image from the current frame 105 // Pre-Mac OS X 10.6, fetch the rendered image from the current frame
105 // buffer and copy it into the TransportDIB. 106 // buffer and copy it into the TransportDIB.
106 // TODO(dspringer): There are a couple of options that can speed this up. 107 // TODO(dspringer): There are a couple of options that can speed this up.
107 // First is to use async reads into a PBO, second is to use SPI that 108 // First is to use async reads into a PBO, second is to use SPI that
108 // allows many tasks to access the same CGSSurface. 109 // allows many tasks to access the same CGSSurface.
109 void* pixel_memory = transport_dib_->memory(); 110 void* pixel_memory = transport_dib_->memory();
110 if (pixel_memory) { 111 if (pixel_memory) {
111 // Note that glReadPixels does an implicit glFlush(). 112 // Note that glReadPixels does an implicit glFlush().
112 glReadPixels(0, 113 glReadPixels(0,
113 0, 114 0,
114 surface_size_.width(), 115 real_surface_size_.width(),
115 surface_size_.height(), 116 real_surface_size_.height(),
116 GL_BGRA, // This pixel format should have no conversion. 117 GL_BGRA, // This pixel format should have no conversion.
117 GL_UNSIGNED_INT_8_8_8_8_REV, 118 GL_UNSIGNED_INT_8_8_8_8_REV,
118 pixel_memory); 119 pixel_memory);
119 } 120 }
120 } 121 }
121 } 122 }
122 123
123 static void AddBooleanValue(CFMutableDictionaryRef dictionary, 124 static void AddBooleanValue(CFMutableDictionaryRef dictionary,
124 const CFStringRef key, 125 const CFStringRef key,
125 bool value) { 126 bool value) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 if (fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT) { 188 if (fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT) {
188 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, 189 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
189 0x8D20, // GL_STENCIL_ATTACHMENT, 190 0x8D20, // GL_STENCIL_ATTACHMENT,
190 GL_RENDERBUFFER_EXT, 191 GL_RENDERBUFFER_EXT,
191 depth_stencil_renderbuffer_); 192 depth_stencil_renderbuffer_);
192 fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 193 fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
193 } 194 }
194 return fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT; 195 return fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT;
195 } 196 }
196 197
198 gfx::Size AcceleratedSurface::ClampToValidDimensions(const gfx::Size& size) {
199 return gfx::Size(std::max(size.width(), 1), std::max(size.height(), 1));
200 }
201
197 bool AcceleratedSurface::MakeCurrent() { 202 bool AcceleratedSurface::MakeCurrent() {
198 if (!gl_context_.get()) 203 if (!gl_context_.get())
199 return false; 204 return false;
200 return gl_context_->MakeCurrent(gl_surface_.get()); 205 return gl_context_->MakeCurrent(gl_surface_.get());
201 } 206 }
202 207
203 void AcceleratedSurface::Clear(const gfx::Rect& rect) { 208 void AcceleratedSurface::Clear(const gfx::Rect& rect) {
204 DCHECK(gl_context_->IsCurrent(gl_surface_.get())); 209 DCHECK(gl_context_->IsCurrent(gl_surface_.get()));
205 glClearColor(0, 0, 0, 0); 210 glClearColor(0, 0, 0, 0);
206 glViewport(0, 0, rect.width(), rect.height()); 211 glViewport(0, 0, rect.width(), rect.height());
(...skipping 16 matching lines...) Expand all
223 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) 228 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL)
224 return 0; 229 return 0;
225 230
226 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); 231 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
227 if (!io_surface_support) 232 if (!io_surface_support)
228 return 0; // Caller can try using SetWindowSizeForTransportDIB(). 233 return 0; // Caller can try using SetWindowSizeForTransportDIB().
229 234
230 if (!MakeCurrent()) 235 if (!MakeCurrent())
231 return 0; 236 return 0;
232 237
238 gfx::Size clamped_size = ClampToValidDimensions(size);
239
233 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on 240 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
234 // Mac OS X and is required for IOSurface interoperability. 241 // Mac OS X and is required for IOSurface interoperability.
235 GLenum target = GL_TEXTURE_RECTANGLE_ARB; 242 GLenum target = GL_TEXTURE_RECTANGLE_ARB;
236 if (allocate_fbo_) { 243 if (allocate_fbo_) {
237 AllocateRenderBuffers(target, size); 244 AllocateRenderBuffers(target, clamped_size);
238 } else if (!texture_) { 245 } else if (!texture_) {
239 // Generate the texture object. 246 // Generate the texture object.
240 glGenTextures(1, &texture_); 247 glGenTextures(1, &texture_);
241 glBindTexture(target, texture_); 248 glBindTexture(target, texture_);
242 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 249 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
243 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 250 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
244 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 251 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
245 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 252 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
246 } 253 }
247 254
248 // Allocate a new IOSurface, which is the GPU resource that can be 255 // Allocate a new IOSurface, which is the GPU resource that can be
249 // shared across processes. 256 // shared across processes.
250 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> properties; 257 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
251 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, 258 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault,
252 0, 259 0,
253 &kCFTypeDictionaryKeyCallBacks, 260 &kCFTypeDictionaryKeyCallBacks,
254 &kCFTypeDictionaryValueCallBacks)); 261 &kCFTypeDictionaryValueCallBacks));
255 AddIntegerValue(properties, 262 AddIntegerValue(properties,
256 io_surface_support->GetKIOSurfaceWidth(), size.width()); 263 io_surface_support->GetKIOSurfaceWidth(),
264 clamped_size.width());
257 AddIntegerValue(properties, 265 AddIntegerValue(properties,
258 io_surface_support->GetKIOSurfaceHeight(), size.height()); 266 io_surface_support->GetKIOSurfaceHeight(),
267 clamped_size.height());
259 AddIntegerValue(properties, 268 AddIntegerValue(properties,
260 io_surface_support->GetKIOSurfaceBytesPerElement(), 4); 269 io_surface_support->GetKIOSurfaceBytesPerElement(), 4);
261 AddBooleanValue(properties, 270 AddBooleanValue(properties,
262 io_surface_support->GetKIOSurfaceIsGlobal(), true); 271 io_surface_support->GetKIOSurfaceIsGlobal(), true);
263 // I believe we should be able to unreference the IOSurfaces without 272 // I believe we should be able to unreference the IOSurfaces without
264 // synchronizing with the browser process because they are 273 // synchronizing with the browser process because they are
265 // ultimately reference counted by the operating system. 274 // ultimately reference counted by the operating system.
266 io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); 275 io_surface_.reset(io_surface_support->IOSurfaceCreate(properties));
267 276
268 // Don't think we need to identify a plane. 277 // Don't think we need to identify a plane.
269 GLuint plane = 0; 278 GLuint plane = 0;
270 io_surface_support->CGLTexImageIOSurface2D( 279 io_surface_support->CGLTexImageIOSurface2D(
271 static_cast<CGLContextObj>(gl_context_->GetHandle()), 280 static_cast<CGLContextObj>(gl_context_->GetHandle()),
272 target, 281 target,
273 GL_RGBA, 282 GL_RGBA,
274 size.width(), 283 clamped_size.width(),
275 size.height(), 284 clamped_size.height(),
276 GL_BGRA, 285 GL_BGRA,
277 GL_UNSIGNED_INT_8_8_8_8_REV, 286 GL_UNSIGNED_INT_8_8_8_8_REV,
278 io_surface_.get(), 287 io_surface_.get(),
279 plane); 288 plane);
280 if (allocate_fbo_) { 289 if (allocate_fbo_) {
281 // Set up the frame buffer object. 290 // Set up the frame buffer object.
282 SetupFrameBufferObject(target); 291 SetupFrameBufferObject(target);
283 } 292 }
284 surface_size_ = size; 293 surface_size_ = size;
294 real_surface_size_ = clamped_size;
285 295
286 // Now send back an identifier for the IOSurface. We originally 296 // Now send back an identifier for the IOSurface. We originally
287 // intended to send back a mach port from IOSurfaceCreateMachPort 297 // intended to send back a mach port from IOSurfaceCreateMachPort
288 // but it looks like Chrome IPC would need to be modified to 298 // but it looks like Chrome IPC would need to be modified to
289 // properly send mach ports between processes. For the time being we 299 // properly send mach ports between processes. For the time being we
290 // make our IOSurfaces global and send back their identifiers. On 300 // make our IOSurfaces global and send back their identifiers. On
291 // the browser process side the identifier is reconstituted into an 301 // the browser process side the identifier is reconstituted into an
292 // IOSurface for on-screen rendering. 302 // IOSurface for on-screen rendering.
293 io_surface_id_ = io_surface_support->IOSurfaceGetID(io_surface_); 303 io_surface_id_ = io_surface_support->IOSurfaceGetID(io_surface_);
294 return io_surface_id_; 304 return io_surface_id_;
295 } 305 }
296 306
297 uint64 AcceleratedSurface::GetSurfaceId() { 307 uint64 AcceleratedSurface::GetSurfaceId() {
298 return io_surface_id_; 308 return io_surface_id_;
299 } 309 }
300 310
301 TransportDIB::Handle AcceleratedSurface::SetTransportDIBSize( 311 TransportDIB::Handle AcceleratedSurface::SetTransportDIBSize(
302 const gfx::Size& size) { 312 const gfx::Size& size) {
303 if (surface_size_ == size) { 313 if (surface_size_ == size) {
304 // Return an invalid handle to indicate to the caller that no new backing 314 // Return an invalid handle to indicate to the caller that no new backing
305 // store allocation occurred. 315 // store allocation occurred.
306 return TransportDIB::DefaultHandleValue(); 316 return TransportDIB::DefaultHandleValue();
307 } 317 }
308 surface_size_ = size; 318 surface_size_ = size;
319 gfx::Size clamped_size = ClampToValidDimensions(size);
320 real_surface_size_ = clamped_size;
309 321
310 // Release the old TransportDIB in the browser. 322 // Release the old TransportDIB in the browser.
311 if (dib_free_callback_.get() && transport_dib_.get()) { 323 if (dib_free_callback_.get() && transport_dib_.get()) {
312 dib_free_callback_->Run(transport_dib_->id()); 324 dib_free_callback_->Run(transport_dib_->id());
313 } 325 }
314 transport_dib_.reset(); 326 transport_dib_.reset();
315 327
316 // Ask the renderer to create a TransportDIB. 328 // Ask the renderer to create a TransportDIB.
317 size_t dib_size = size.width() * 4 * size.height(); // 4 bytes per pixel. 329 size_t dib_size =
330 clamped_size.width() * 4 * clamped_size.height(); // 4 bytes per pixel.
318 TransportDIB::Handle dib_handle; 331 TransportDIB::Handle dib_handle;
319 if (dib_alloc_callback_.get()) { 332 if (dib_alloc_callback_.get()) {
320 dib_alloc_callback_->Run(dib_size, &dib_handle); 333 dib_alloc_callback_->Run(dib_size, &dib_handle);
321 } 334 }
322 if (!TransportDIB::is_valid_handle(dib_handle)) { 335 if (!TransportDIB::is_valid_handle(dib_handle)) {
323 // If the allocator fails, it means the DIB was not created in the browser, 336 // If the allocator fails, it means the DIB was not created in the browser,
324 // so there is no need to run the deallocator here. 337 // so there is no need to run the deallocator here.
325 return TransportDIB::DefaultHandleValue(); 338 return TransportDIB::DefaultHandleValue();
326 } 339 }
327 transport_dib_.reset(TransportDIB::Map(dib_handle)); 340 transport_dib_.reset(TransportDIB::Map(dib_handle));
328 if (transport_dib_.get() == NULL) { 341 if (transport_dib_.get() == NULL) {
329 // TODO(dspringer): if the Map() fails, should the deallocator be run so 342 // TODO(dspringer): if the Map() fails, should the deallocator be run so
330 // that the DIB is deallocated in the browser? 343 // that the DIB is deallocated in the browser?
331 return TransportDIB::DefaultHandleValue(); 344 return TransportDIB::DefaultHandleValue();
332 } 345 }
333 346
334 if (allocate_fbo_) { 347 if (allocate_fbo_) {
335 DCHECK(gl_context_->IsCurrent(gl_surface_.get())); 348 DCHECK(gl_context_->IsCurrent(gl_surface_.get()));
336 // Set up the render buffers and reserve enough space on the card for the 349 // Set up the render buffers and reserve enough space on the card for the
337 // framebuffer texture. 350 // framebuffer texture.
338 GLenum target = GL_TEXTURE_RECTANGLE_ARB; 351 GLenum target = GL_TEXTURE_RECTANGLE_ARB;
339 AllocateRenderBuffers(target, size); 352 AllocateRenderBuffers(target, clamped_size);
340 glTexImage2D(target, 353 glTexImage2D(target,
341 0, // mipmap level 0 354 0, // mipmap level 0
342 GL_RGBA8, // internal pixel format 355 GL_RGBA8, // internal pixel format
343 size.width(), 356 clamped_size.width(),
344 size.height(), 357 clamped_size.height(),
345 0, // 0 border 358 0, // 0 border
346 GL_BGRA, // Used for consistency 359 GL_BGRA, // Used for consistency
347 GL_UNSIGNED_INT_8_8_8_8_REV, 360 GL_UNSIGNED_INT_8_8_8_8_REV,
348 NULL); // No data, just reserve room on the card. 361 NULL); // No data, just reserve room on the card.
349 SetupFrameBufferObject(target); 362 SetupFrameBufferObject(target);
350 } 363 }
351 return transport_dib_->handle(); 364 return transport_dib_->handle();
352 } 365 }
353 366
354 void AcceleratedSurface::SetTransportDIBAllocAndFree( 367 void AcceleratedSurface::SetTransportDIBAllocAndFree(
355 Callback2<size_t, TransportDIB::Handle*>::Type* allocator, 368 Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
356 Callback1<TransportDIB::Id>::Type* deallocator) { 369 Callback1<TransportDIB::Id>::Type* deallocator) {
357 dib_alloc_callback_.reset(allocator); 370 dib_alloc_callback_.reset(allocator);
358 dib_free_callback_.reset(deallocator); 371 dib_free_callback_.reset(deallocator);
359 } 372 }
OLDNEW
« no previous file with comments | « ui/gfx/surface/accelerated_surface_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698