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 |