|
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "TextureHostOGL.h" |
|
7 #include "GLContext.h" // for GLContext, etc |
|
8 #include "GLSharedHandleHelpers.h" |
|
9 #include "GLUploadHelpers.h" |
|
10 #include "GLReadTexImageHelper.h" |
|
11 #include "SharedSurface.h" // for SharedSurface |
|
12 #include "SharedSurfaceEGL.h" // for SharedSurface_EGLImage |
|
13 #include "SharedSurfaceGL.h" // for SharedSurface_GLTexture, etc |
|
14 #include "SurfaceStream.h" // for SurfaceStream |
|
15 #include "SurfaceTypes.h" // for SharedSurfaceType, etc |
|
16 #include "gfx2DGlue.h" // for ContentForFormat, etc |
|
17 #include "gfxReusableSurfaceWrapper.h" // for gfxReusableSurfaceWrapper |
|
18 #include "mozilla/gfx/2D.h" // for DataSourceSurface |
|
19 #include "mozilla/gfx/BaseSize.h" // for BaseSize |
|
20 #include "mozilla/layers/CompositorOGL.h" // for CompositorOGL |
|
21 #ifdef MOZ_WIDGET_GONK |
|
22 # include "GrallocImages.h" // for GrallocImage |
|
23 # include "EGLImageHelpers.h" |
|
24 #endif |
|
25 #include "mozilla/layers/ISurfaceAllocator.h" |
|
26 #include "mozilla/layers/YCbCrImageDataSerializer.h" |
|
27 #include "mozilla/layers/GrallocTextureHost.h" |
|
28 #include "nsPoint.h" // for nsIntPoint |
|
29 #include "nsRegion.h" // for nsIntRegion |
|
30 #include "GfxTexturesReporter.h" // for GfxTexturesReporter |
|
31 #include "GLBlitTextureImageHelper.h" |
|
32 #ifdef XP_MACOSX |
|
33 #include "SharedSurfaceIO.h" |
|
34 #include "mozilla/layers/MacIOSurfaceTextureHostOGL.h" |
|
35 #endif |
|
36 #include "GeckoProfiler.h" |
|
37 |
|
38 using namespace mozilla::gl; |
|
39 using namespace mozilla::gfx; |
|
40 |
|
41 namespace mozilla { |
|
42 namespace layers { |
|
43 |
|
44 class Compositor; |
|
45 |
|
46 TemporaryRef<CompositableBackendSpecificData> |
|
47 CreateCompositableBackendSpecificDataOGL() |
|
48 { |
|
49 #ifdef MOZ_WIDGET_GONK |
|
50 return new CompositableDataGonkOGL(); |
|
51 #else |
|
52 return nullptr; |
|
53 #endif |
|
54 } |
|
55 |
|
56 TemporaryRef<TextureHost> |
|
57 CreateTextureHostOGL(const SurfaceDescriptor& aDesc, |
|
58 ISurfaceAllocator* aDeallocator, |
|
59 TextureFlags aFlags) |
|
60 { |
|
61 RefPtr<TextureHost> result; |
|
62 switch (aDesc.type()) { |
|
63 case SurfaceDescriptor::TSurfaceDescriptorShmem: |
|
64 case SurfaceDescriptor::TSurfaceDescriptorMemory: { |
|
65 result = CreateBackendIndependentTextureHost(aDesc, |
|
66 aDeallocator, aFlags); |
|
67 break; |
|
68 } |
|
69 case SurfaceDescriptor::TSharedTextureDescriptor: { |
|
70 const SharedTextureDescriptor& desc = aDesc.get_SharedTextureDescriptor(); |
|
71 result = new SharedTextureHostOGL(aFlags, |
|
72 desc.shareType(), |
|
73 desc.handle(), |
|
74 desc.size(), |
|
75 desc.inverted()); |
|
76 break; |
|
77 } |
|
78 case SurfaceDescriptor::TSurfaceStreamDescriptor: { |
|
79 const SurfaceStreamDescriptor& desc = aDesc.get_SurfaceStreamDescriptor(); |
|
80 result = new StreamTextureHostOGL(aFlags, desc); |
|
81 break; |
|
82 } |
|
83 #ifdef XP_MACOSX |
|
84 case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: { |
|
85 const SurfaceDescriptorMacIOSurface& desc = |
|
86 aDesc.get_SurfaceDescriptorMacIOSurface(); |
|
87 result = new MacIOSurfaceTextureHostOGL(aFlags, desc); |
|
88 break; |
|
89 } |
|
90 #endif |
|
91 #ifdef MOZ_WIDGET_GONK |
|
92 case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: { |
|
93 const NewSurfaceDescriptorGralloc& desc = |
|
94 aDesc.get_NewSurfaceDescriptorGralloc(); |
|
95 result = new GrallocTextureHostOGL(aFlags, desc); |
|
96 break; |
|
97 } |
|
98 #endif |
|
99 default: return nullptr; |
|
100 } |
|
101 return result.forget(); |
|
102 } |
|
103 |
|
104 static gl::TextureImage::Flags |
|
105 FlagsToGLFlags(TextureFlags aFlags) |
|
106 { |
|
107 uint32_t result = TextureImage::NoFlags; |
|
108 |
|
109 if (aFlags & TEXTURE_USE_NEAREST_FILTER) |
|
110 result |= TextureImage::UseNearestFilter; |
|
111 if (aFlags & TEXTURE_NEEDS_Y_FLIP) |
|
112 result |= TextureImage::NeedsYFlip; |
|
113 if (aFlags & TEXTURE_DISALLOW_BIGIMAGE) |
|
114 result |= TextureImage::DisallowBigImage; |
|
115 |
|
116 return static_cast<gl::TextureImage::Flags>(result); |
|
117 } |
|
118 |
|
119 GLenum |
|
120 WrapMode(gl::GLContext *aGl, bool aAllowRepeat) |
|
121 { |
|
122 if (aAllowRepeat && |
|
123 (aGl->IsExtensionSupported(GLContext::ARB_texture_non_power_of_two) || |
|
124 aGl->IsExtensionSupported(GLContext::OES_texture_npot))) { |
|
125 return LOCAL_GL_REPEAT; |
|
126 } |
|
127 return LOCAL_GL_CLAMP_TO_EDGE; |
|
128 } |
|
129 |
|
130 CompositableDataGonkOGL::CompositableDataGonkOGL() |
|
131 : mTexture(0) |
|
132 { |
|
133 } |
|
134 CompositableDataGonkOGL::~CompositableDataGonkOGL() |
|
135 { |
|
136 DeleteTextureIfPresent(); |
|
137 } |
|
138 |
|
139 gl::GLContext* |
|
140 CompositableDataGonkOGL::gl() const |
|
141 { |
|
142 return mCompositor ? mCompositor->gl() : nullptr; |
|
143 } |
|
144 |
|
145 void CompositableDataGonkOGL::SetCompositor(Compositor* aCompositor) |
|
146 { |
|
147 mCompositor = static_cast<CompositorOGL*>(aCompositor); |
|
148 } |
|
149 |
|
150 void CompositableDataGonkOGL::ClearData() |
|
151 { |
|
152 CompositableBackendSpecificData::ClearData(); |
|
153 DeleteTextureIfPresent(); |
|
154 } |
|
155 |
|
156 GLuint CompositableDataGonkOGL::GetTexture() |
|
157 { |
|
158 if (!mTexture) { |
|
159 if (gl()->MakeCurrent()) { |
|
160 gl()->fGenTextures(1, &mTexture); |
|
161 } |
|
162 } |
|
163 return mTexture; |
|
164 } |
|
165 |
|
166 void |
|
167 CompositableDataGonkOGL::DeleteTextureIfPresent() |
|
168 { |
|
169 if (mTexture) { |
|
170 if (gl()->MakeCurrent()) { |
|
171 gl()->fDeleteTextures(1, &mTexture); |
|
172 } |
|
173 mTexture = 0; |
|
174 } |
|
175 } |
|
176 |
|
177 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 |
|
178 bool |
|
179 TextureHostOGL::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence) |
|
180 { |
|
181 if (!aReleaseFence.get() || !aReleaseFence->isValid()) { |
|
182 // HWC might not provide Fence. |
|
183 // In this case, HWC implicitly handles buffer's fence. |
|
184 return false; |
|
185 } |
|
186 |
|
187 if (!mReleaseFence.get()) { |
|
188 mReleaseFence = aReleaseFence; |
|
189 } else { |
|
190 android::sp<android::Fence> mergedFence = android::Fence::merge( |
|
191 android::String8::format("TextureHostOGL"), |
|
192 mReleaseFence, aReleaseFence); |
|
193 if (!mergedFence.get()) { |
|
194 // synchronization is broken, the best we can do is hope fences |
|
195 // signal in order so the new fence will act like a union. |
|
196 // This error handling is same as android::ConsumerBase does. |
|
197 mReleaseFence = aReleaseFence; |
|
198 return false; |
|
199 } |
|
200 mReleaseFence = mergedFence; |
|
201 } |
|
202 return true; |
|
203 } |
|
204 |
|
205 android::sp<android::Fence> |
|
206 TextureHostOGL::GetAndResetReleaseFence() |
|
207 { |
|
208 // Hold previous ReleaseFence to prevent Fence delivery failure via gecko IPC. |
|
209 mPrevReleaseFence = mReleaseFence; |
|
210 // Reset current ReleaseFence. |
|
211 mReleaseFence = android::Fence::NO_FENCE; |
|
212 return mPrevReleaseFence; |
|
213 } |
|
214 #endif |
|
215 |
|
216 bool |
|
217 TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, |
|
218 nsIntRegion* aDestRegion, |
|
219 gfx::IntPoint* aSrcOffset) |
|
220 { |
|
221 MOZ_ASSERT(mGL); |
|
222 if (!mGL) { |
|
223 NS_WARNING("trying to update TextureImageTextureSourceOGL without a GLContext"); |
|
224 return false; |
|
225 } |
|
226 MOZ_ASSERT(aSurface); |
|
227 |
|
228 IntSize size = aSurface->GetSize(); |
|
229 if (!mTexImage || |
|
230 (mTexImage->GetSize() != size && !aSrcOffset) || |
|
231 mTexImage->GetContentType() != gfx::ContentForFormat(aSurface->GetFormat())) { |
|
232 if (mFlags & TEXTURE_DISALLOW_BIGIMAGE) { |
|
233 mTexImage = CreateBasicTextureImage(mGL, size, |
|
234 gfx::ContentForFormat(aSurface->GetFormat()), |
|
235 WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), |
|
236 FlagsToGLFlags(mFlags), |
|
237 SurfaceFormatToImageFormat(aSurface->GetFormat())); |
|
238 } else { |
|
239 // XXX - clarify which size we want to use. IncrementalContentHost will |
|
240 // require the size of the destination surface to be different from |
|
241 // the size of aSurface. |
|
242 // See bug 893300 (tracks the implementation of ContentHost for new textures). |
|
243 mTexImage = CreateTextureImage(mGL, |
|
244 size, |
|
245 gfx::ContentForFormat(aSurface->GetFormat()), |
|
246 WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), |
|
247 FlagsToGLFlags(mFlags), |
|
248 SurfaceFormatToImageFormat(aSurface->GetFormat())); |
|
249 } |
|
250 ClearCachedFilter(); |
|
251 } |
|
252 |
|
253 mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset); |
|
254 |
|
255 if (mTexImage->InUpdate()) { |
|
256 mTexImage->EndUpdate(); |
|
257 } |
|
258 return true; |
|
259 } |
|
260 |
|
261 void |
|
262 TextureImageTextureSourceOGL::EnsureBuffer(const nsIntSize& aSize, |
|
263 gfxContentType aContentType) |
|
264 { |
|
265 if (!mTexImage || |
|
266 mTexImage->GetSize() != aSize.ToIntSize() || |
|
267 mTexImage->GetContentType() != aContentType) { |
|
268 mTexImage = CreateTextureImage(mGL, |
|
269 aSize.ToIntSize(), |
|
270 aContentType, |
|
271 WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), |
|
272 FlagsToGLFlags(mFlags)); |
|
273 } |
|
274 mTexImage->Resize(aSize.ToIntSize()); |
|
275 } |
|
276 |
|
277 void |
|
278 TextureImageTextureSourceOGL::CopyTo(const nsIntRect& aSourceRect, |
|
279 DataTextureSource *aDest, |
|
280 const nsIntRect& aDestRect) |
|
281 { |
|
282 MOZ_ASSERT(aDest->AsSourceOGL(), "Incompatible destination type!"); |
|
283 TextureImageTextureSourceOGL *dest = |
|
284 aDest->AsSourceOGL()->AsTextureImageTextureSource(); |
|
285 MOZ_ASSERT(dest, "Incompatible destination type!"); |
|
286 |
|
287 mGL->BlitTextureImageHelper()->BlitTextureImage(mTexImage, aSourceRect, |
|
288 dest->mTexImage, aDestRect); |
|
289 dest->mTexImage->MarkValid(); |
|
290 } |
|
291 |
|
292 void |
|
293 TextureImageTextureSourceOGL::SetCompositor(Compositor* aCompositor) |
|
294 { |
|
295 CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); |
|
296 |
|
297 if (!glCompositor || (mGL != glCompositor->gl())) { |
|
298 DeallocateDeviceData(); |
|
299 mGL = glCompositor ? glCompositor->gl() : nullptr; |
|
300 } |
|
301 } |
|
302 |
|
303 gfx::IntSize |
|
304 TextureImageTextureSourceOGL::GetSize() const |
|
305 { |
|
306 if (mTexImage) { |
|
307 if (mIterating) { |
|
308 return mTexImage->GetTileRect().Size(); |
|
309 } |
|
310 return mTexImage->GetSize(); |
|
311 } |
|
312 NS_WARNING("Trying to query the size of an empty TextureSource."); |
|
313 return gfx::IntSize(0, 0); |
|
314 } |
|
315 |
|
316 gfx::SurfaceFormat |
|
317 TextureImageTextureSourceOGL::GetFormat() const |
|
318 { |
|
319 if (mTexImage) { |
|
320 return mTexImage->GetTextureFormat(); |
|
321 } |
|
322 NS_WARNING("Trying to query the format of an empty TextureSource."); |
|
323 return gfx::SurfaceFormat::UNKNOWN; |
|
324 } |
|
325 |
|
326 nsIntRect TextureImageTextureSourceOGL::GetTileRect() |
|
327 { |
|
328 return ThebesIntRect(mTexImage->GetTileRect()); |
|
329 } |
|
330 |
|
331 void |
|
332 TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) |
|
333 { |
|
334 MOZ_ASSERT(mTexImage, |
|
335 "Trying to bind a TextureSource that does not have an underlying GL texture."); |
|
336 mTexImage->BindTexture(aTextureUnit); |
|
337 SetFilter(mGL, aFilter); |
|
338 } |
|
339 |
|
340 SharedTextureSourceOGL::SharedTextureSourceOGL(CompositorOGL* aCompositor, |
|
341 gl::SharedTextureHandle aHandle, |
|
342 gfx::SurfaceFormat aFormat, |
|
343 GLenum aTarget, |
|
344 GLenum aWrapMode, |
|
345 SharedTextureShareType aShareType, |
|
346 gfx::IntSize aSize) |
|
347 : mSize(aSize) |
|
348 , mCompositor(aCompositor) |
|
349 , mSharedHandle(aHandle) |
|
350 , mFormat(aFormat) |
|
351 , mShareType(aShareType) |
|
352 , mTextureTarget(aTarget) |
|
353 , mWrapMode(aWrapMode) |
|
354 {} |
|
355 |
|
356 void |
|
357 SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) |
|
358 { |
|
359 if (!gl()) { |
|
360 NS_WARNING("Trying to bind a texture without a GLContext"); |
|
361 return; |
|
362 } |
|
363 GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit); |
|
364 |
|
365 gl()->fActiveTexture(aTextureUnit); |
|
366 gl()->fBindTexture(mTextureTarget, tex); |
|
367 if (!AttachSharedHandle(gl(), mShareType, mSharedHandle)) { |
|
368 NS_ERROR("Failed to bind shared texture handle"); |
|
369 return; |
|
370 } |
|
371 ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); |
|
372 } |
|
373 |
|
374 void |
|
375 SharedTextureSourceOGL::DetachSharedHandle() |
|
376 { |
|
377 if (!gl()) { |
|
378 return; |
|
379 } |
|
380 gl::DetachSharedHandle(gl(), mShareType, mSharedHandle); |
|
381 } |
|
382 |
|
383 void |
|
384 SharedTextureSourceOGL::SetCompositor(Compositor* aCompositor) |
|
385 { |
|
386 mCompositor = static_cast<CompositorOGL*>(aCompositor); |
|
387 } |
|
388 |
|
389 bool |
|
390 SharedTextureSourceOGL::IsValid() const |
|
391 { |
|
392 return !!gl(); |
|
393 } |
|
394 |
|
395 gl::GLContext* |
|
396 SharedTextureSourceOGL::gl() const |
|
397 { |
|
398 return mCompositor ? mCompositor->gl() : nullptr; |
|
399 } |
|
400 |
|
401 gfx::Matrix4x4 |
|
402 SharedTextureSourceOGL::GetTextureTransform() |
|
403 { |
|
404 SharedHandleDetails handleDetails; |
|
405 if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) { |
|
406 NS_WARNING("Could not get shared handle details"); |
|
407 return gfx::Matrix4x4(); |
|
408 } |
|
409 |
|
410 return handleDetails.mTextureTransform; |
|
411 } |
|
412 |
|
413 SharedTextureHostOGL::SharedTextureHostOGL(TextureFlags aFlags, |
|
414 gl::SharedTextureShareType aShareType, |
|
415 gl::SharedTextureHandle aSharedHandle, |
|
416 gfx::IntSize aSize, |
|
417 bool inverted) |
|
418 : TextureHost(aFlags) |
|
419 , mSize(aSize) |
|
420 , mCompositor(nullptr) |
|
421 , mSharedHandle(aSharedHandle) |
|
422 , mShareType(aShareType) |
|
423 { |
|
424 } |
|
425 |
|
426 SharedTextureHostOGL::~SharedTextureHostOGL() |
|
427 { |
|
428 // If need to deallocate textures, call DeallocateSharedData() before |
|
429 // the destructor |
|
430 } |
|
431 |
|
432 gl::GLContext* |
|
433 SharedTextureHostOGL::gl() const |
|
434 { |
|
435 return mCompositor ? mCompositor->gl() : nullptr; |
|
436 } |
|
437 |
|
438 bool |
|
439 SharedTextureHostOGL::Lock() |
|
440 { |
|
441 if (!mCompositor) { |
|
442 return false; |
|
443 } |
|
444 |
|
445 if (!mTextureSource) { |
|
446 // XXX on android GetSharedHandleDetails can call into Java which we'd |
|
447 // rather not do from the compositor |
|
448 SharedHandleDetails handleDetails; |
|
449 if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) { |
|
450 NS_WARNING("Could not get shared handle details"); |
|
451 return false; |
|
452 } |
|
453 |
|
454 GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE; |
|
455 mTextureSource = new SharedTextureSourceOGL(mCompositor, |
|
456 mSharedHandle, |
|
457 handleDetails.mTextureFormat, |
|
458 handleDetails.mTarget, |
|
459 wrapMode, |
|
460 mShareType, |
|
461 mSize); |
|
462 } |
|
463 return true; |
|
464 } |
|
465 |
|
466 void |
|
467 SharedTextureHostOGL::Unlock() |
|
468 { |
|
469 if (!mTextureSource) { |
|
470 return; |
|
471 } |
|
472 mTextureSource->DetachSharedHandle(); |
|
473 } |
|
474 |
|
475 void |
|
476 SharedTextureHostOGL::SetCompositor(Compositor* aCompositor) |
|
477 { |
|
478 CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); |
|
479 mCompositor = glCompositor; |
|
480 if (mTextureSource) { |
|
481 mTextureSource->SetCompositor(glCompositor); |
|
482 } |
|
483 } |
|
484 |
|
485 gfx::SurfaceFormat |
|
486 SharedTextureHostOGL::GetFormat() const |
|
487 { |
|
488 MOZ_ASSERT(mTextureSource); |
|
489 return mTextureSource->GetFormat(); |
|
490 } |
|
491 |
|
492 void |
|
493 StreamTextureSourceOGL::BindTexture(GLenum activetex, gfx::Filter aFilter) |
|
494 { |
|
495 MOZ_ASSERT(gl()); |
|
496 gl()->fActiveTexture(activetex); |
|
497 gl()->fBindTexture(mTextureTarget, mTextureHandle); |
|
498 SetFilter(gl(), aFilter); |
|
499 } |
|
500 |
|
501 bool |
|
502 StreamTextureSourceOGL::RetrieveTextureFromStream() |
|
503 { |
|
504 gl()->MakeCurrent(); |
|
505 |
|
506 SharedSurface* sharedSurf = mStream->SwapConsumer(); |
|
507 if (!sharedSurf) { |
|
508 // We don't have a valid surf to show yet. |
|
509 return false; |
|
510 } |
|
511 |
|
512 gl()->MakeCurrent(); |
|
513 |
|
514 mSize = IntSize(sharedSurf->Size().width, sharedSurf->Size().height); |
|
515 |
|
516 DataSourceSurface* toUpload = nullptr; |
|
517 switch (sharedSurf->Type()) { |
|
518 case SharedSurfaceType::GLTextureShare: { |
|
519 SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf); |
|
520 mTextureHandle = glTexSurf->ConsTexture(gl()); |
|
521 mTextureTarget = glTexSurf->ConsTextureTarget(); |
|
522 MOZ_ASSERT(mTextureHandle); |
|
523 mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 |
|
524 : SurfaceFormat::R8G8B8X8; |
|
525 break; |
|
526 } |
|
527 case SharedSurfaceType::EGLImageShare: { |
|
528 SharedSurface_EGLImage* eglImageSurf = |
|
529 SharedSurface_EGLImage::Cast(sharedSurf); |
|
530 |
|
531 eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget); |
|
532 MOZ_ASSERT(mTextureHandle); |
|
533 mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 |
|
534 : SurfaceFormat::R8G8B8X8; |
|
535 break; |
|
536 } |
|
537 #ifdef XP_MACOSX |
|
538 case SharedSurfaceType::IOSurface: { |
|
539 SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf); |
|
540 mTextureHandle = glTexSurf->ConsTexture(gl()); |
|
541 mTextureTarget = glTexSurf->ConsTextureTarget(); |
|
542 MOZ_ASSERT(mTextureHandle); |
|
543 mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 |
|
544 : SurfaceFormat::R8G8B8X8; |
|
545 break; |
|
546 } |
|
547 #endif |
|
548 case SharedSurfaceType::Basic: { |
|
549 toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData(); |
|
550 MOZ_ASSERT(toUpload); |
|
551 break; |
|
552 } |
|
553 default: |
|
554 MOZ_CRASH("Invalid SharedSurface type."); |
|
555 } |
|
556 |
|
557 if (toUpload) { |
|
558 // mBounds seems to end up as (0,0,0,0) a lot, so don't use it? |
|
559 nsIntSize size(ThebesIntSize(toUpload->GetSize())); |
|
560 nsIntRect rect(nsIntPoint(0,0), size); |
|
561 nsIntRegion bounds(rect); |
|
562 mFormat = UploadSurfaceToTexture(gl(), |
|
563 toUpload, |
|
564 bounds, |
|
565 mUploadTexture, |
|
566 true); |
|
567 mTextureHandle = mUploadTexture; |
|
568 mTextureTarget = LOCAL_GL_TEXTURE_2D; |
|
569 } |
|
570 |
|
571 MOZ_ASSERT(mTextureHandle); |
|
572 gl()->fBindTexture(mTextureTarget, mTextureHandle); |
|
573 gl()->fTexParameteri(mTextureTarget, |
|
574 LOCAL_GL_TEXTURE_WRAP_S, |
|
575 LOCAL_GL_CLAMP_TO_EDGE); |
|
576 gl()->fTexParameteri(mTextureTarget, |
|
577 LOCAL_GL_TEXTURE_WRAP_T, |
|
578 LOCAL_GL_CLAMP_TO_EDGE); |
|
579 |
|
580 ClearCachedFilter(); |
|
581 |
|
582 return true; |
|
583 } |
|
584 |
|
585 void |
|
586 StreamTextureSourceOGL::DeallocateDeviceData() |
|
587 { |
|
588 if (mUploadTexture) { |
|
589 MOZ_ASSERT(gl()); |
|
590 gl()->MakeCurrent(); |
|
591 gl()->fDeleteTextures(1, &mUploadTexture); |
|
592 mUploadTexture = 0; |
|
593 mTextureHandle = 0; |
|
594 } |
|
595 } |
|
596 |
|
597 gl::GLContext* |
|
598 StreamTextureSourceOGL::gl() const |
|
599 { |
|
600 return mCompositor ? mCompositor->gl() : nullptr; |
|
601 } |
|
602 |
|
603 void |
|
604 StreamTextureSourceOGL::SetCompositor(Compositor* aCompositor) |
|
605 { |
|
606 mCompositor = static_cast<CompositorOGL*>(aCompositor); |
|
607 } |
|
608 |
|
609 StreamTextureHostOGL::StreamTextureHostOGL(TextureFlags aFlags, |
|
610 const SurfaceStreamDescriptor& aDesc) |
|
611 : TextureHost(aFlags) |
|
612 { |
|
613 mStream = SurfaceStream::FromHandle(aDesc.handle()); |
|
614 MOZ_ASSERT(mStream); |
|
615 } |
|
616 |
|
617 StreamTextureHostOGL::~StreamTextureHostOGL() |
|
618 { |
|
619 // If need to deallocate textures, call DeallocateSharedData() before |
|
620 // the destructor |
|
621 } |
|
622 |
|
623 bool |
|
624 StreamTextureHostOGL::Lock() |
|
625 { |
|
626 if (!mCompositor) { |
|
627 return false; |
|
628 } |
|
629 |
|
630 if (!mTextureSource) { |
|
631 mTextureSource = new StreamTextureSourceOGL(mCompositor, |
|
632 mStream); |
|
633 } |
|
634 |
|
635 return mTextureSource->RetrieveTextureFromStream(); |
|
636 } |
|
637 |
|
638 void |
|
639 StreamTextureHostOGL::Unlock() |
|
640 { |
|
641 } |
|
642 |
|
643 void |
|
644 StreamTextureHostOGL::SetCompositor(Compositor* aCompositor) |
|
645 { |
|
646 CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); |
|
647 mCompositor = glCompositor; |
|
648 if (mTextureSource) { |
|
649 mTextureSource->SetCompositor(glCompositor); |
|
650 } |
|
651 } |
|
652 |
|
653 gfx::SurfaceFormat |
|
654 StreamTextureHostOGL::GetFormat() const |
|
655 { |
|
656 MOZ_ASSERT(mTextureSource); |
|
657 return mTextureSource->GetFormat(); |
|
658 } |
|
659 |
|
660 gfx::IntSize |
|
661 StreamTextureHostOGL::GetSize() const |
|
662 { |
|
663 MOZ_ASSERT(mTextureSource); |
|
664 return mTextureSource->GetSize(); |
|
665 } |
|
666 |
|
667 } // namespace |
|
668 } // namespace |