LCOV - code coverage report
Current view: top level - gfx/layers/client - ImageClient.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 145 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "ImageClient.h"
       7             : 
       8             : #include <stdint.h>                     // for uint32_t
       9             : 
      10             : #include "ClientLayerManager.h"         // for ClientLayer
      11             : #include "ImageContainer.h"             // for Image, PlanarYCbCrImage, etc
      12             : #include "ImageTypes.h"                 // for ImageFormat::PLANAR_YCBCR, etc
      13             : #include "GLImages.h"                   // for SurfaceTextureImage::Data, etc
      14             : #include "gfx2DGlue.h"                  // for ImageFormatToSurfaceFormat
      15             : #include "gfxPlatform.h"                // for gfxPlatform
      16             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
      17             : #include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed
      18             : #include "mozilla/gfx/2D.h"
      19             : #include "mozilla/gfx/BaseSize.h"       // for BaseSize
      20             : #include "mozilla/gfx/Point.h"          // for IntSize
      21             : #include "mozilla/gfx/Types.h"          // for SurfaceFormat, etc
      22             : #include "mozilla/layers/CompositableClient.h"  // for CompositableClient
      23             : #include "mozilla/layers/CompositableForwarder.h"
      24             : #include "mozilla/layers/CompositorTypes.h"  // for CompositableType, etc
      25             : #include "mozilla/layers/ISurfaceAllocator.h"
      26             : #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
      27             : #include "mozilla/layers/ShadowLayers.h"  // for ShadowLayerForwarder
      28             : #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
      29             : #include "mozilla/layers/TextureClientOGL.h"  // for SurfaceTextureClient
      30             : #include "mozilla/mozalloc.h"           // for operator delete, etc
      31             : #include "nsCOMPtr.h"                   // for already_AddRefed
      32             : #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
      33             : #include "nsISupportsImpl.h"            // for Image::Release, etc
      34             : #include "nsRect.h"                     // for mozilla::gfx::IntRect
      35             : 
      36             : namespace mozilla {
      37             : namespace layers {
      38             : 
      39             : using namespace mozilla::gfx;
      40             : 
      41             : /* static */ already_AddRefed<ImageClient>
      42           0 : ImageClient::CreateImageClient(CompositableType aCompositableHostType,
      43             :                                CompositableForwarder* aForwarder,
      44             :                                TextureFlags aFlags)
      45             : {
      46           0 :   RefPtr<ImageClient> result = nullptr;
      47           0 :   switch (aCompositableHostType) {
      48             :   case CompositableType::IMAGE:
      49           0 :     result = new ImageClientSingle(aForwarder, aFlags, CompositableType::IMAGE);
      50           0 :     break;
      51             :   case CompositableType::IMAGE_BRIDGE:
      52           0 :     result = new ImageClientBridge(aForwarder, aFlags);
      53           0 :     break;
      54             :   case CompositableType::UNKNOWN:
      55           0 :     result = nullptr;
      56           0 :     break;
      57             :   default:
      58           0 :     MOZ_CRASH("GFX: unhandled program type image");
      59             :   }
      60             : 
      61           0 :   NS_ASSERTION(result, "Failed to create ImageClient");
      62             : 
      63           0 :   return result.forget();
      64             : }
      65             : 
      66             : void
      67           0 : ImageClient::RemoveTexture(TextureClient* aTexture)
      68             : {
      69           0 :   GetForwarder()->RemoveTextureFromCompositable(this, aTexture);
      70           0 : }
      71             : 
      72           0 : ImageClientSingle::ImageClientSingle(CompositableForwarder* aFwd,
      73             :                                      TextureFlags aFlags,
      74           0 :                                      CompositableType aType)
      75           0 :   : ImageClient(aFwd, aFlags, aType)
      76             : {
      77           0 : }
      78             : 
      79           0 : TextureInfo ImageClientSingle::GetTextureInfo() const
      80             : {
      81           0 :   return TextureInfo(CompositableType::IMAGE);
      82             : }
      83             : 
      84             : void
      85           0 : ImageClientSingle::FlushAllImages()
      86             : {
      87           0 :   MOZ_ASSERT(GetForwarder()->GetTextureForwarder()->UsesImageBridge());
      88             : 
      89           0 :   for (auto& b : mBuffers) {
      90           0 :     RemoveTexture(b.mTextureClient);
      91             :   }
      92           0 :   mBuffers.Clear();
      93           0 : }
      94             : 
      95             : /* static */ already_AddRefed<TextureClient>
      96           0 : ImageClient::CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwarder)
      97             : {
      98           0 :   RefPtr<TextureClient> texture;
      99           0 :   if (aImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
     100           0 :     PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(aImage);
     101           0 :     const PlanarYCbCrData* data = ycbcr->GetData();
     102           0 :     if (!data) {
     103           0 :       return nullptr;
     104             :     }
     105           0 :     texture = TextureClient::CreateForYCbCr(aForwarder,
     106           0 :                                             data->mYSize, data->mCbCrSize, data->mStereoMode,
     107           0 :                                             data->mYUVColorSpace,
     108           0 :                                             TextureFlags::DEFAULT);
     109           0 :     if (!texture) {
     110           0 :       return nullptr;
     111             :     }
     112             : 
     113           0 :     TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY);
     114           0 :     if (!autoLock.Succeeded()) {
     115           0 :       return nullptr;
     116             :     }
     117             : 
     118           0 :     bool status = UpdateYCbCrTextureClient(texture, *data);
     119           0 :     MOZ_ASSERT(status);
     120           0 :     if (!status) {
     121           0 :       return nullptr;
     122             :     }
     123           0 :   } else if (aImage->GetFormat() == ImageFormat::SURFACE_TEXTURE ||
     124           0 :              aImage->GetFormat() == ImageFormat::EGLIMAGE) {
     125           0 :     gfx::IntSize size = aImage->GetSize();
     126             : 
     127           0 :     if (aImage->GetFormat() == ImageFormat::EGLIMAGE) {
     128           0 :       EGLImageImage* typedImage = aImage->AsEGLImageImage();
     129           0 :       texture = EGLImageTextureData::CreateTextureClient(
     130           0 :         typedImage, size, aForwarder->GetTextureForwarder(), TextureFlags::DEFAULT);
     131             : #ifdef MOZ_WIDGET_ANDROID
     132             :     } else if (aImage->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
     133             :       SurfaceTextureImage* typedImage = aImage->AsSurfaceTextureImage();
     134             :       texture = AndroidSurfaceTextureData::CreateTextureClient(
     135             :         typedImage->GetHandle(), size, typedImage->GetContinuous(), typedImage->GetOriginPos(),
     136             :         aForwarder->GetTextureForwarder(), TextureFlags::DEFAULT);
     137             : #endif
     138             :     } else {
     139           0 :       MOZ_ASSERT(false, "Bad ImageFormat.");
     140             :     }
     141             :   } else {
     142           0 :     RefPtr<gfx::SourceSurface> surface = aImage->GetAsSourceSurface();
     143           0 :     MOZ_ASSERT(surface);
     144           0 :     texture = TextureClient::CreateForDrawing(aForwarder, surface->GetFormat(), aImage->GetSize(),
     145           0 :                                               BackendSelector::Content, TextureFlags::DEFAULT);
     146           0 :     if (!texture) {
     147           0 :       return nullptr;
     148             :     }
     149             : 
     150           0 :     MOZ_ASSERT(texture->CanExposeDrawTarget());
     151             : 
     152           0 :     if (!texture->Lock(OpenMode::OPEN_WRITE_ONLY)) {
     153           0 :       return nullptr;
     154             :     }
     155             : 
     156             :     {
     157             :       // We must not keep a reference to the DrawTarget after it has been unlocked.
     158           0 :       DrawTarget* dt = texture->BorrowDrawTarget();
     159           0 :       if (!dt) {
     160           0 :         gfxWarning() << "ImageClientSingle::UpdateImage failed in BorrowDrawTarget";
     161           0 :         return nullptr;
     162             :       }
     163           0 :       MOZ_ASSERT(surface.get());
     164           0 :       dt->CopySurface(surface, IntRect(IntPoint(), surface->GetSize()), IntPoint());
     165             :     }
     166             : 
     167           0 :     texture->Unlock();
     168             :   }
     169           0 :   return texture.forget();
     170             : }
     171             : 
     172             : bool
     173           0 : ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags)
     174             : {
     175           0 :   AutoTArray<ImageContainer::OwningImage,4> images;
     176             :   uint32_t generationCounter;
     177           0 :   aContainer->GetCurrentImages(&images, &generationCounter);
     178             : 
     179           0 :   if (mLastUpdateGenerationCounter == generationCounter) {
     180           0 :     return true;
     181             :   }
     182           0 :   mLastUpdateGenerationCounter = generationCounter;
     183             : 
     184           0 :   for (int32_t i = images.Length() - 1; i >= 0; --i) {
     185           0 :     if (!images[i].mImage->IsValid()) {
     186             :       // Don't try to update to an invalid image.
     187           0 :       images.RemoveElementAt(i);
     188             :     }
     189             :   }
     190           0 :   if (images.IsEmpty()) {
     191             :     // This can happen if a ClearAllImages raced with SetCurrentImages from
     192             :     // another thread and ClearImagesFromImageBridge ran after the
     193             :     // SetCurrentImages call but before UpdateImageClientNow.
     194             :     // This can also happen if all images in the list are invalid.
     195             :     // We return true because the caller would attempt to recreate the
     196             :     // ImageClient otherwise, and that isn't going to help.
     197           0 :     for (auto& b : mBuffers) {
     198           0 :       RemoveTexture(b.mTextureClient);
     199             :     }
     200           0 :     mBuffers.Clear();
     201           0 :     return true;
     202             :   }
     203             : 
     204           0 :   nsTArray<Buffer> newBuffers;
     205           0 :   AutoTArray<CompositableForwarder::TimedTextureClient,4> textures;
     206             : 
     207           0 :   for (auto& img : images) {
     208           0 :     Image* image = img.mImage;
     209             : 
     210           0 :     RefPtr<TextureClient> texture = image->GetTextureClient(GetForwarder());
     211           0 :     const bool hasTextureClient = !!texture;
     212             : 
     213           0 :     for (int32_t i = mBuffers.Length() - 1; i >= 0; --i) {
     214           0 :       if (mBuffers[i].mImageSerial == image->GetSerial()) {
     215           0 :         if (hasTextureClient) {
     216           0 :           MOZ_ASSERT(image->GetTextureClient(GetForwarder()) == mBuffers[i].mTextureClient);
     217             :         } else {
     218           0 :           texture = mBuffers[i].mTextureClient;
     219             :         }
     220             :         // Remove this element from mBuffers so mBuffers only contains
     221             :         // images that aren't present in 'images'
     222           0 :         mBuffers.RemoveElementAt(i);
     223             :       }
     224             :     }
     225             : 
     226           0 :     if (!texture) {
     227             :       // Slow path, we should not be hitting it very often and if we do it means
     228             :       // we are using an Image class that is not backed by textureClient and we
     229             :       // should fix it.
     230           0 :       texture = CreateTextureClientForImage(image, GetForwarder());
     231             :     }
     232             : 
     233           0 :     if (!texture) {
     234           0 :       return false;
     235             :     }
     236             : 
     237             :     // We check if the texture's allocator is still open, since in between media
     238             :     // decoding a frame and adding it to the compositable, we could have
     239             :     // restarted the GPU process.
     240           0 :     if (!texture->GetAllocator()->IPCOpen()) {
     241           0 :       continue;
     242             :     }
     243           0 :     if (!AddTextureClient(texture)) {
     244           0 :       return false;
     245             :     }
     246             : 
     247           0 :     CompositableForwarder::TimedTextureClient* t = textures.AppendElement();
     248           0 :     t->mTextureClient = texture;
     249           0 :     t->mTimeStamp = img.mTimeStamp;
     250           0 :     t->mPictureRect = image->GetPictureRect();
     251           0 :     t->mFrameID = img.mFrameID;
     252           0 :     t->mProducerID = img.mProducerID;
     253             : 
     254           0 :     Buffer* newBuf = newBuffers.AppendElement();
     255           0 :     newBuf->mImageSerial = image->GetSerial();
     256           0 :     newBuf->mTextureClient = texture;
     257             : 
     258           0 :     texture->SyncWithObject(GetForwarder()->GetSyncObject());
     259             :   }
     260             : 
     261           0 :   GetForwarder()->UseTextures(this, textures);
     262             : 
     263           0 :   for (auto& b : mBuffers) {
     264           0 :     RemoveTexture(b.mTextureClient);
     265             :   }
     266           0 :   mBuffers.SwapElements(newBuffers);
     267             : 
     268           0 :   return true;
     269             : }
     270             : 
     271             : bool
     272           0 : ImageClientSingle::AddTextureClient(TextureClient* aTexture)
     273             : {
     274           0 :   MOZ_ASSERT((mTextureFlags & aTexture->GetFlags()) == mTextureFlags);
     275           0 :   return CompositableClient::AddTextureClient(aTexture);
     276             : }
     277             : 
     278             : void
     279           0 : ImageClientSingle::OnDetach()
     280             : {
     281           0 :   mBuffers.Clear();
     282           0 : }
     283             : 
     284           0 : ImageClient::ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
     285           0 :                          CompositableType aType)
     286             : : CompositableClient(aFwd, aFlags)
     287             : , mLayer(nullptr)
     288             : , mType(aType)
     289           0 : , mLastUpdateGenerationCounter(0)
     290           0 : {}
     291             : 
     292           0 : ImageClientBridge::ImageClientBridge(CompositableForwarder* aFwd,
     293           0 :                                      TextureFlags aFlags)
     294           0 : : ImageClient(aFwd, aFlags, CompositableType::IMAGE_BRIDGE)
     295             : {
     296           0 : }
     297             : 
     298             : bool
     299           0 : ImageClientBridge::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags)
     300             : {
     301           0 :   if (!GetForwarder() || !mLayer) {
     302           0 :     return false;
     303             :   }
     304           0 :   if (mAsyncContainerHandle == aContainer->GetAsyncContainerHandle()) {
     305           0 :     return true;
     306             :   }
     307             : 
     308           0 :   mAsyncContainerHandle = aContainer->GetAsyncContainerHandle();
     309           0 :   if (!mAsyncContainerHandle) {
     310             :     // If we couldn't contact a working ImageBridgeParent, just return.
     311           0 :     return true;
     312             :   }
     313             : 
     314           0 :   static_cast<ShadowLayerForwarder*>(GetForwarder())->AttachAsyncCompositable(mAsyncContainerHandle, mLayer);
     315           0 :   return true;
     316             : }
     317             : 
     318             : } // namespace layers
     319             : } // namespace mozilla

Generated by: LCOV version 1.13