Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #if defined(ENABLE_GPU) | 5 #if defined(ENABLE_GPU) |
| 6 | 6 |
| 7 #include "content/common/gpu/image_transport_surface.h" | 7 #include "content/common/gpu/image_transport_surface.h" |
| 8 | 8 |
| 9 #include "base/mac/scoped_cftyperef.h" | 9 #include "base/mac/scoped_cftyperef.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 // GLSurface implementation | 30 // GLSurface implementation |
| 31 virtual bool Initialize() OVERRIDE; | 31 virtual bool Initialize() OVERRIDE; |
| 32 virtual void Destroy() OVERRIDE; | 32 virtual void Destroy() OVERRIDE; |
| 33 virtual bool IsOffscreen() OVERRIDE; | 33 virtual bool IsOffscreen() OVERRIDE; |
| 34 virtual bool SwapBuffers() OVERRIDE; | 34 virtual bool SwapBuffers() OVERRIDE; |
| 35 virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE; | 35 virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE; |
| 36 virtual std::string GetExtensions() OVERRIDE; | 36 virtual std::string GetExtensions() OVERRIDE; |
| 37 virtual gfx::Size GetSize() OVERRIDE; | 37 virtual gfx::Size GetSize() OVERRIDE; |
| 38 virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE; | 38 virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE; |
| 39 virtual unsigned int GetBackingFrameBufferObject() OVERRIDE; | 39 virtual unsigned int GetBackingFrameBufferObject() OVERRIDE; |
| 40 virtual void SetBufferAllocation(BufferAllocationState state) OVERRIDE; | |
| 40 | 41 |
| 41 protected: | 42 protected: |
| 42 // ImageTransportSurface implementation | 43 // ImageTransportSurface implementation |
| 43 virtual void OnNewSurfaceACK(uint64 surface_handle, | 44 virtual void OnNewSurfaceACK(uint64 surface_handle, |
| 44 TransportDIB::Handle shm_handle) OVERRIDE; | 45 TransportDIB::Handle shm_handle) OVERRIDE; |
| 45 virtual void OnBuffersSwappedACK() OVERRIDE; | 46 virtual void OnBuffersSwappedACK() OVERRIDE; |
| 46 virtual void OnPostSubBufferACK() OVERRIDE; | 47 virtual void OnPostSubBufferACK() OVERRIDE; |
| 47 virtual void OnResizeViewACK() OVERRIDE; | 48 virtual void OnResizeViewACK() OVERRIDE; |
| 48 virtual void OnResize(gfx::Size size) OVERRIDE; | 49 virtual void OnResize(gfx::Size size) OVERRIDE; |
| 49 | 50 |
| 50 private: | 51 private: |
| 51 virtual ~IOSurfaceImageTransportSurface() OVERRIDE; | 52 virtual ~IOSurfaceImageTransportSurface() OVERRIDE; |
| 52 | 53 |
| 54 void UnrefIOSurface(); | |
| 55 void CreateIOSurface(); | |
| 56 | |
| 57 BufferAllocationState buffer_allocation_state_; | |
| 58 | |
| 53 uint32 fbo_id_; | 59 uint32 fbo_id_; |
| 54 GLuint texture_id_; | 60 GLuint texture_id_; |
| 55 | 61 |
| 56 base::mac::ScopedCFTypeRef<CFTypeRef> io_surface_; | 62 base::mac::ScopedCFTypeRef<CFTypeRef> io_surface_; |
| 57 | 63 |
| 58 // The id of |io_surface_| or 0 if that's NULL. | 64 // The id of |io_surface_| or 0 if that's NULL. |
| 59 uint64 io_surface_handle_; | 65 uint64 io_surface_handle_; |
| 60 | 66 |
| 61 // Weak pointer to the context that this was last made current to. | 67 // Weak pointer to the context that this was last made current to. |
| 62 gfx::GLContext* context_; | 68 gfx::GLContext* context_; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 84 base::mac::ScopedCFTypeRef<CFNumberRef> number( | 90 base::mac::ScopedCFTypeRef<CFNumberRef> number( |
| 85 CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); | 91 CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); |
| 86 CFDictionaryAddValue(dictionary, key, number.get()); | 92 CFDictionaryAddValue(dictionary, key, number.get()); |
| 87 } | 93 } |
| 88 | 94 |
| 89 IOSurfaceImageTransportSurface::IOSurfaceImageTransportSurface( | 95 IOSurfaceImageTransportSurface::IOSurfaceImageTransportSurface( |
| 90 GpuChannelManager* manager, | 96 GpuChannelManager* manager, |
| 91 GpuCommandBufferStub* stub, | 97 GpuCommandBufferStub* stub, |
| 92 gfx::PluginWindowHandle handle) | 98 gfx::PluginWindowHandle handle) |
| 93 : gfx::NoOpGLSurfaceCGL(gfx::Size(1, 1)), | 99 : gfx::NoOpGLSurfaceCGL(gfx::Size(1, 1)), |
| 100 buffer_allocation_state_(BUFFER_ALLOCATION_FRONT_AND_BACK), | |
| 94 fbo_id_(0), | 101 fbo_id_(0), |
| 95 texture_id_(0), | 102 texture_id_(0), |
| 96 io_surface_handle_(0), | 103 io_surface_handle_(0), |
| 97 context_(NULL), | 104 context_(NULL), |
| 98 made_current_(false) { | 105 made_current_(false) { |
| 99 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); | 106 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); |
| 100 } | 107 } |
| 101 | 108 |
| 102 IOSurfaceImageTransportSurface::~IOSurfaceImageTransportSurface() { | 109 IOSurfaceImageTransportSurface::~IOSurfaceImageTransportSurface() { |
| 103 Destroy(); | 110 Destroy(); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 134 bool IOSurfaceImageTransportSurface::IsOffscreen() { | 141 bool IOSurfaceImageTransportSurface::IsOffscreen() { |
| 135 return false; | 142 return false; |
| 136 } | 143 } |
| 137 | 144 |
| 138 bool IOSurfaceImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) { | 145 bool IOSurfaceImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) { |
| 139 context_ = context; | 146 context_ = context; |
| 140 | 147 |
| 141 if (made_current_) | 148 if (made_current_) |
| 142 return true; | 149 return true; |
| 143 | 150 |
| 144 glGenFramebuffersEXT(1, &fbo_id_); | |
| 145 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); | |
| 146 OnResize(gfx::Size(1, 1)); | 151 OnResize(gfx::Size(1, 1)); |
| 147 | 152 |
| 148 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); | |
| 149 if (status != GL_FRAMEBUFFER_COMPLETE) { | |
| 150 DLOG(ERROR) << "Framebuffer incomplete."; | |
| 151 return false; | |
| 152 } | |
| 153 | |
| 154 made_current_ = true; | 153 made_current_ = true; |
| 155 return true; | 154 return true; |
| 156 } | 155 } |
| 157 | 156 |
| 158 unsigned int IOSurfaceImageTransportSurface::GetBackingFrameBufferObject() { | 157 unsigned int IOSurfaceImageTransportSurface::GetBackingFrameBufferObject() { |
| 159 return fbo_id_; | 158 return fbo_id_; |
| 160 } | 159 } |
| 161 | 160 |
| 161 void IOSurfaceImageTransportSurface::SetBufferAllocation( | |
| 162 BufferAllocationState state) { | |
| 163 if (buffer_allocation_state_ == state) | |
| 164 return; | |
| 165 buffer_allocation_state_ = state; | |
| 166 | |
| 167 switch (state) { | |
| 168 case BUFFER_ALLOCATION_FRONT_AND_BACK: | |
| 169 CreateIOSurface(); | |
| 170 break; | |
| 171 | |
| 172 case BUFFER_ALLOCATION_FRONT_ONLY: | |
| 173 break; | |
| 174 | |
| 175 case BUFFER_ALLOCATION_NONE: | |
| 176 UnrefIOSurface(); | |
| 177 helper_->Suspend(); | |
| 178 break; | |
| 179 | |
| 180 default: | |
| 181 NOTREACHED(); | |
| 182 } | |
| 183 } | |
| 184 | |
| 162 bool IOSurfaceImageTransportSurface::SwapBuffers() { | 185 bool IOSurfaceImageTransportSurface::SwapBuffers() { |
| 163 glFlush(); | 186 glFlush(); |
| 164 | 187 |
| 165 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | 188 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| 166 params.surface_handle = io_surface_handle_; | 189 params.surface_handle = io_surface_handle_; |
| 167 helper_->SendAcceleratedSurfaceBuffersSwapped(params); | 190 helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| 168 | 191 |
| 169 helper_->SetScheduled(false); | 192 helper_->SetScheduled(false); |
| 170 return true; | 193 return true; |
| 171 } | 194 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 uint64 surface_handle, | 233 uint64 surface_handle, |
| 211 TransportDIB::Handle /* shm_handle */) { | 234 TransportDIB::Handle /* shm_handle */) { |
| 212 NOTREACHED(); | 235 NOTREACHED(); |
| 213 } | 236 } |
| 214 | 237 |
| 215 void IOSurfaceImageTransportSurface::OnResizeViewACK() { | 238 void IOSurfaceImageTransportSurface::OnResizeViewACK() { |
| 216 NOTREACHED(); | 239 NOTREACHED(); |
| 217 } | 240 } |
| 218 | 241 |
| 219 void IOSurfaceImageTransportSurface::OnResize(gfx::Size size) { | 242 void IOSurfaceImageTransportSurface::OnResize(gfx::Size size) { |
| 220 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); | |
| 221 | |
| 222 // Caching |context_| from OnMakeCurrent. It should still be current. | 243 // Caching |context_| from OnMakeCurrent. It should still be current. |
| 223 DCHECK(context_->IsCurrent(this)); | 244 DCHECK(context_->IsCurrent(this)); |
| 224 | 245 |
| 225 size_ = size; | 246 size_ = size; |
| 226 | 247 |
| 248 CreateIOSurface(); | |
| 249 } | |
| 250 | |
| 251 void IOSurfaceImageTransportSurface::UnrefIOSurface() { | |
| 252 if (fbo_id_) { | |
| 253 GLenum target = GL_TEXTURE_RECTANGLE_ARB; | |
| 254 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
|
Ken Russell (switch to Gerrit)
2012/04/18 02:00:27
How about a DCHECK that the context is current, as
jbates
2012/04/18 23:01:58
Done.
| |
| 255 GL_COLOR_ATTACHMENT0_EXT, | |
| 256 target, | |
| 257 0, | |
| 258 0); | |
| 259 | |
| 260 glDeleteFramebuffersEXT(1, &fbo_id_); | |
| 261 | |
| 262 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
| 263 fbo_id_ = 0; | |
| 264 } | |
| 265 | |
| 227 if (texture_id_) { | 266 if (texture_id_) { |
| 228 glDeleteTextures(1, &texture_id_); | 267 glDeleteTextures(1, &texture_id_); |
| 229 texture_id_ = 0; | 268 texture_id_ = 0; |
| 230 } | 269 } |
| 231 | 270 |
| 232 glGenTextures(1, &texture_id_); | 271 io_surface_.reset(); |
| 233 | 272 |
| 273 io_surface_handle_ = 0; | |
| 274 } | |
| 275 | |
| 276 void IOSurfaceImageTransportSurface::CreateIOSurface() { | |
| 234 GLint previous_texture_id = 0; | 277 GLint previous_texture_id = 0; |
| 235 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); | 278 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); |
| 236 | 279 |
| 280 UnrefIOSurface(); | |
| 281 | |
| 282 glGenFramebuffersEXT(1, &fbo_id_); | |
| 283 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); | |
| 284 | |
| 285 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); | |
| 286 | |
| 287 glGenTextures(1, &texture_id_); | |
| 288 | |
| 237 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on | 289 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on |
| 238 // Mac OS X and is required for IOSurface interoperability. | 290 // Mac OS X and is required for IOSurface interoperability. |
| 239 GLenum target = GL_TEXTURE_RECTANGLE_ARB; | 291 GLenum target = GL_TEXTURE_RECTANGLE_ARB; |
| 240 glBindTexture(target, texture_id_); | 292 glBindTexture(target, texture_id_); |
| 241 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 293 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 242 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 294 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 243 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 295 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 244 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 296 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 245 | 297 |
| 246 GLint previous_fbo_id = 0; | |
| 247 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previous_fbo_id); | |
| 248 | |
| 249 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); | |
| 250 | |
| 251 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | 298 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, |
| 252 GL_COLOR_ATTACHMENT0_EXT, | 299 GL_COLOR_ATTACHMENT0_EXT, |
| 253 target, | 300 target, |
| 254 texture_id_, | 301 texture_id_, |
| 255 0); | 302 0); |
| 256 | 303 |
| 257 // Allocate a new IOSurface, which is the GPU resource that can be | 304 // Allocate a new IOSurface, which is the GPU resource that can be |
| 258 // shared across processes. | 305 // shared across processes. |
| 259 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> properties; | 306 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> properties; |
| 260 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, | 307 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 271 io_surface_support->GetKIOSurfaceBytesPerElement(), 4); | 318 io_surface_support->GetKIOSurfaceBytesPerElement(), 4); |
| 272 AddBooleanValue(properties, | 319 AddBooleanValue(properties, |
| 273 io_surface_support->GetKIOSurfaceIsGlobal(), true); | 320 io_surface_support->GetKIOSurfaceIsGlobal(), true); |
| 274 // I believe we should be able to unreference the IOSurfaces without | 321 // I believe we should be able to unreference the IOSurfaces without |
| 275 // synchronizing with the browser process because they are | 322 // synchronizing with the browser process because they are |
| 276 // ultimately reference counted by the operating system. | 323 // ultimately reference counted by the operating system. |
| 277 io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); | 324 io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); |
| 278 | 325 |
| 279 // Don't think we need to identify a plane. | 326 // Don't think we need to identify a plane. |
| 280 GLuint plane = 0; | 327 GLuint plane = 0; |
| 281 io_surface_support->CGLTexImageIOSurface2D( | 328 CGLError cglerror = |
| 282 static_cast<CGLContextObj>(context_->GetHandle()), | 329 io_surface_support->CGLTexImageIOSurface2D( |
| 283 target, | 330 static_cast<CGLContextObj>(context_->GetHandle()), |
| 284 GL_RGBA, | 331 target, |
| 285 size_.width(), | 332 GL_RGBA, |
| 286 size_.height(), | 333 size_.width(), |
| 287 GL_BGRA, | 334 size_.height(), |
| 288 GL_UNSIGNED_INT_8_8_8_8_REV, | 335 GL_BGRA, |
| 289 io_surface_.get(), | 336 GL_UNSIGNED_INT_8_8_8_8_REV, |
| 290 plane); | 337 io_surface_.get(), |
| 338 plane); | |
| 339 if (cglerror != kCGLNoError) { | |
| 340 DLOG(ERROR) << "CGLTexImageIOSurface2D: " << cglerror; | |
| 341 UnrefIOSurface(); | |
| 342 return; | |
| 343 } | |
| 291 | 344 |
| 292 io_surface_handle_ = io_surface_support->IOSurfaceGetID(io_surface_); | 345 io_surface_handle_ = io_surface_support->IOSurfaceGetID(io_surface_); |
| 293 glFlush(); | 346 glFlush(); |
| 294 | 347 |
| 295 glBindTexture(target, previous_texture_id); | 348 glBindTexture(target, previous_texture_id); |
| 296 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, previous_fbo_id); | 349 // The FBO remains bound for this GL context. |
|
Ken Russell (switch to Gerrit)
2012/04/18 02:00:27
Please document in the header that OnResize change
jbates
2012/04/18 23:01:58
Done.
| |
| 297 } | 350 } |
| 298 | 351 |
| 299 } // namespace | 352 } // namespace |
| 300 | 353 |
| 301 // static | 354 // static |
| 302 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface( | 355 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface( |
| 303 GpuChannelManager* manager, | 356 GpuChannelManager* manager, |
| 304 GpuCommandBufferStub* stub, | 357 GpuCommandBufferStub* stub, |
| 305 const gfx::GLSurfaceHandle& surface_handle) { | 358 const gfx::GLSurfaceHandle& surface_handle) { |
| 306 scoped_refptr<gfx::GLSurface> surface; | 359 scoped_refptr<gfx::GLSurface> surface; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 321 NOTREACHED(); | 374 NOTREACHED(); |
| 322 return NULL; | 375 return NULL; |
| 323 } | 376 } |
| 324 if (surface->Initialize()) | 377 if (surface->Initialize()) |
| 325 return surface; | 378 return surface; |
| 326 else | 379 else |
| 327 return NULL; | 380 return NULL; |
| 328 } | 381 } |
| 329 | 382 |
| 330 #endif // defined(USE_GPU) | 383 #endif // defined(USE_GPU) |
| OLD | NEW |