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 DCHECK(context_->IsCurrent(this)); |
| 253 |
| 254 if (fbo_id_) { |
| 255 glDeleteFramebuffersEXT(1, &fbo_id_); |
| 256 fbo_id_ = 0; |
| 257 } |
| 258 |
227 if (texture_id_) { | 259 if (texture_id_) { |
228 glDeleteTextures(1, &texture_id_); | 260 glDeleteTextures(1, &texture_id_); |
229 texture_id_ = 0; | 261 texture_id_ = 0; |
230 } | 262 } |
231 | 263 |
232 glGenTextures(1, &texture_id_); | 264 io_surface_.reset(); |
| 265 io_surface_handle_ = 0; |
| 266 } |
233 | 267 |
| 268 void IOSurfaceImageTransportSurface::CreateIOSurface() { |
234 GLint previous_texture_id = 0; | 269 GLint previous_texture_id = 0; |
235 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); | 270 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); |
236 | 271 |
| 272 UnrefIOSurface(); |
| 273 |
| 274 glGenFramebuffersEXT(1, &fbo_id_); |
| 275 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); |
| 276 |
| 277 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); |
| 278 |
| 279 glGenTextures(1, &texture_id_); |
| 280 |
237 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on | 281 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on |
238 // Mac OS X and is required for IOSurface interoperability. | 282 // Mac OS X and is required for IOSurface interoperability. |
239 GLenum target = GL_TEXTURE_RECTANGLE_ARB; | 283 GLenum target = GL_TEXTURE_RECTANGLE_ARB; |
240 glBindTexture(target, texture_id_); | 284 glBindTexture(target, texture_id_); |
241 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 285 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
242 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 286 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
243 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 287 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
244 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 288 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
245 | 289 |
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, | 290 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, |
252 GL_COLOR_ATTACHMENT0_EXT, | 291 GL_COLOR_ATTACHMENT0_EXT, |
253 target, | 292 target, |
254 texture_id_, | 293 texture_id_, |
255 0); | 294 0); |
256 | 295 |
257 // Allocate a new IOSurface, which is the GPU resource that can be | 296 // Allocate a new IOSurface, which is the GPU resource that can be |
258 // shared across processes. | 297 // shared across processes. |
259 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> properties; | 298 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> properties; |
260 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, | 299 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, |
(...skipping 10 matching lines...) Expand all Loading... |
271 io_surface_support->GetKIOSurfaceBytesPerElement(), 4); | 310 io_surface_support->GetKIOSurfaceBytesPerElement(), 4); |
272 AddBooleanValue(properties, | 311 AddBooleanValue(properties, |
273 io_surface_support->GetKIOSurfaceIsGlobal(), true); | 312 io_surface_support->GetKIOSurfaceIsGlobal(), true); |
274 // I believe we should be able to unreference the IOSurfaces without | 313 // I believe we should be able to unreference the IOSurfaces without |
275 // synchronizing with the browser process because they are | 314 // synchronizing with the browser process because they are |
276 // ultimately reference counted by the operating system. | 315 // ultimately reference counted by the operating system. |
277 io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); | 316 io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); |
278 | 317 |
279 // Don't think we need to identify a plane. | 318 // Don't think we need to identify a plane. |
280 GLuint plane = 0; | 319 GLuint plane = 0; |
281 io_surface_support->CGLTexImageIOSurface2D( | 320 CGLError cglerror = |
282 static_cast<CGLContextObj>(context_->GetHandle()), | 321 io_surface_support->CGLTexImageIOSurface2D( |
283 target, | 322 static_cast<CGLContextObj>(context_->GetHandle()), |
284 GL_RGBA, | 323 target, |
285 size_.width(), | 324 GL_RGBA, |
286 size_.height(), | 325 size_.width(), |
287 GL_BGRA, | 326 size_.height(), |
288 GL_UNSIGNED_INT_8_8_8_8_REV, | 327 GL_BGRA, |
289 io_surface_.get(), | 328 GL_UNSIGNED_INT_8_8_8_8_REV, |
290 plane); | 329 io_surface_.get(), |
| 330 plane); |
| 331 if (cglerror != kCGLNoError) { |
| 332 DLOG(ERROR) << "CGLTexImageIOSurface2D: " << cglerror; |
| 333 UnrefIOSurface(); |
| 334 return; |
| 335 } |
291 | 336 |
292 io_surface_handle_ = io_surface_support->IOSurfaceGetID(io_surface_); | 337 io_surface_handle_ = io_surface_support->IOSurfaceGetID(io_surface_); |
293 glFlush(); | 338 glFlush(); |
294 | 339 |
295 glBindTexture(target, previous_texture_id); | 340 glBindTexture(target, previous_texture_id); |
296 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, previous_fbo_id); | 341 // The FBO remains bound for this GL context. |
297 } | 342 } |
298 | 343 |
299 } // namespace | 344 } // namespace |
300 | 345 |
301 // static | 346 // static |
302 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface( | 347 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface( |
303 GpuChannelManager* manager, | 348 GpuChannelManager* manager, |
304 GpuCommandBufferStub* stub, | 349 GpuCommandBufferStub* stub, |
305 const gfx::GLSurfaceHandle& surface_handle) { | 350 const gfx::GLSurfaceHandle& surface_handle) { |
306 scoped_refptr<gfx::GLSurface> surface; | 351 scoped_refptr<gfx::GLSurface> surface; |
(...skipping 14 matching lines...) Expand all Loading... |
321 NOTREACHED(); | 366 NOTREACHED(); |
322 return NULL; | 367 return NULL; |
323 } | 368 } |
324 if (surface->Initialize()) | 369 if (surface->Initialize()) |
325 return surface; | 370 return surface; |
326 else | 371 else |
327 return NULL; | 372 return NULL; |
328 } | 373 } |
329 | 374 |
330 #endif // defined(USE_GPU) | 375 #endif // defined(USE_GPU) |
OLD | NEW |