gfx/layers/opengl/TextureHostOGL.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial