gfx/layers/client/ImageClient.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 #include "ImageClient.h"
     7 #include <stdint.h>                     // for uint32_t
     8 #include "ImageContainer.h"             // for Image, PlanarYCbCrImage, etc
     9 #include "ImageTypes.h"                 // for ImageFormat::PLANAR_YCBCR, etc
    10 #include "SharedTextureImage.h"         // for SharedTextureImage::Data, etc
    11 #include "gfx2DGlue.h"                  // for ImageFormatToSurfaceFormat
    12 #include "gfxPlatform.h"                // for gfxPlatform
    13 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    14 #include "mozilla/RefPtr.h"             // for RefPtr, TemporaryRef
    15 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
    16 #include "mozilla/gfx/Point.h"          // for IntSize
    17 #include "mozilla/gfx/Types.h"          // for SurfaceFormat, etc
    18 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient
    19 #include "mozilla/layers/CompositableForwarder.h"
    20 #include "mozilla/layers/CompositorTypes.h"  // for CompositableType, etc
    21 #include "mozilla/layers/ISurfaceAllocator.h"
    22 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
    23 #include "mozilla/layers/ShadowLayers.h"  // for ShadowLayerForwarder
    24 #include "mozilla/layers/SharedPlanarYCbCrImage.h"
    25 #include "mozilla/layers/SharedRGBImage.h"
    26 #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
    27 #include "mozilla/layers/TextureClientOGL.h"  // for SharedTextureClientOGL
    28 #include "mozilla/mozalloc.h"           // for operator delete, etc
    29 #include "nsAutoPtr.h"                  // for nsRefPtr
    30 #include "nsCOMPtr.h"                   // for already_AddRefed
    31 #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
    32 #include "nsISupportsImpl.h"            // for Image::Release, etc
    33 #include "nsRect.h"                     // for nsIntRect
    34 #include "mozilla/gfx/2D.h"
    35 #ifdef MOZ_WIDGET_GONK
    36 #include "GrallocImages.h"
    37 #endif
    39 using namespace mozilla::gfx;
    41 namespace mozilla {
    42 namespace layers {
    44 /* static */ TemporaryRef<ImageClient>
    45 ImageClient::CreateImageClient(CompositableType aCompositableHostType,
    46                                CompositableForwarder* aForwarder,
    47                                TextureFlags aFlags)
    48 {
    49   RefPtr<ImageClient> result = nullptr;
    50   switch (aCompositableHostType) {
    51   case COMPOSITABLE_IMAGE:
    52   case BUFFER_IMAGE_SINGLE:
    53     result = new ImageClientSingle(aForwarder, aFlags, COMPOSITABLE_IMAGE);
    54     break;
    55   case BUFFER_IMAGE_BUFFERED:
    56     result = new ImageClientBuffered(aForwarder, aFlags, COMPOSITABLE_IMAGE);
    57     break;
    58   case BUFFER_BRIDGE:
    59     result = new ImageClientBridge(aForwarder, aFlags);
    60     break;
    61   case BUFFER_UNKNOWN:
    62     result = nullptr;
    63     break;
    64   default:
    65     MOZ_CRASH("unhandled program type");
    66   }
    68   NS_ASSERTION(result, "Failed to create ImageClient");
    70   return result.forget();
    71 }
    73 ImageClientSingle::ImageClientSingle(CompositableForwarder* aFwd,
    74                                      TextureFlags aFlags,
    75                                      CompositableType aType)
    76   : ImageClient(aFwd, aFlags, aType)
    77 {
    78 }
    80 ImageClientBuffered::ImageClientBuffered(CompositableForwarder* aFwd,
    81                                          TextureFlags aFlags,
    82                                          CompositableType aType)
    83   : ImageClientSingle(aFwd, aFlags, aType)
    84 {
    85 }
    87 TextureInfo ImageClientSingle::GetTextureInfo() const
    88 {
    89   return TextureInfo(COMPOSITABLE_IMAGE);
    90 }
    92 void
    93 ImageClientSingle::FlushAllImages(bool aExceptFront)
    94 {
    95   if (!aExceptFront && mFrontBuffer) {
    96     GetForwarder()->RemoveTextureFromCompositable(this, mFrontBuffer);
    97     mFrontBuffer = nullptr;
    98   }
    99 }
   101 void
   102 ImageClientBuffered::FlushAllImages(bool aExceptFront)
   103 {
   104   if (!aExceptFront && mFrontBuffer) {
   105     GetForwarder()->RemoveTextureFromCompositable(this, mFrontBuffer);
   106     mFrontBuffer = nullptr;
   107   }
   108   if (mBackBuffer) {
   109     GetForwarder()->RemoveTextureFromCompositable(this, mBackBuffer);
   110     mBackBuffer = nullptr;
   111   }
   112 }
   114 bool
   115 ImageClientSingle::UpdateImage(ImageContainer* aContainer,
   116                                uint32_t aContentFlags)
   117 {
   118   bool isSwapped = false;
   119   return UpdateImageInternal(aContainer, aContentFlags, &isSwapped);
   120 }
   122 bool
   123 ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer,
   124                                        uint32_t aContentFlags, bool* aIsSwapped)
   125 {
   126   AutoLockImage autoLock(aContainer);
   127   *aIsSwapped = false;
   129   Image *image = autoLock.GetImage();
   130   if (!image) {
   131     return false;
   132   }
   134   if (mLastPaintedImageSerial == image->GetSerial()) {
   135     return true;
   136   }
   138   if (image->AsSharedImage() && image->AsSharedImage()->GetTextureClient(this)) {
   139     // fast path: no need to allocate and/or copy image data
   140     RefPtr<TextureClient> texture = image->AsSharedImage()->GetTextureClient(this);
   143     if (mFrontBuffer) {
   144       GetForwarder()->RemoveTextureFromCompositable(this, mFrontBuffer);
   145     }
   146     mFrontBuffer = texture;
   147     if (!AddTextureClient(texture)) {
   148       mFrontBuffer = nullptr;
   149       return false;
   150     }
   151     GetForwarder()->UpdatedTexture(this, texture, nullptr);
   152     GetForwarder()->UseTexture(this, texture);
   153   } else if (image->GetFormat() == ImageFormat::PLANAR_YCBCR) {
   154     PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image);
   155     const PlanarYCbCrData* data = ycbcr->GetData();
   156     if (!data) {
   157       return false;
   158     }
   160     if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
   161       GetForwarder()->RemoveTextureFromCompositable(this, mFrontBuffer);
   162       mFrontBuffer = nullptr;
   163     }
   165     bool bufferCreated = false;
   166     if (!mFrontBuffer) {
   167       mFrontBuffer = CreateBufferTextureClient(gfx::SurfaceFormat::YUV, TEXTURE_FLAGS_DEFAULT);
   168       gfx::IntSize ySize(data->mYSize.width, data->mYSize.height);
   169       gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height);
   170       if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize, data->mStereoMode)) {
   171         mFrontBuffer = nullptr;
   172         return false;
   173       }
   174       bufferCreated = true;
   175     }
   177     if (!mFrontBuffer->Lock(OPEN_WRITE_ONLY)) {
   178       mFrontBuffer = nullptr;
   179       return false;
   180     }
   181     bool status = mFrontBuffer->AsTextureClientYCbCr()->UpdateYCbCr(*data);
   182     mFrontBuffer->Unlock();
   184     if (bufferCreated) {
   185       if (!AddTextureClient(mFrontBuffer)) {
   186         mFrontBuffer = nullptr;
   187         return false;
   188       }
   189     }
   191     if (status) {
   192       GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr);
   193       GetForwarder()->UseTexture(this, mFrontBuffer);
   194     } else {
   195       MOZ_ASSERT(false);
   196       return false;
   197     }
   199   } else if (image->GetFormat() == ImageFormat::SHARED_TEXTURE) {
   200     SharedTextureImage* sharedImage = static_cast<SharedTextureImage*>(image);
   201     const SharedTextureImage::Data *data = sharedImage->GetData();
   202     gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
   204     if (mFrontBuffer) {
   205       GetForwarder()->RemoveTextureFromCompositable(this, mFrontBuffer);
   206       mFrontBuffer = nullptr;
   207     }
   209     RefPtr<SharedTextureClientOGL> buffer = new SharedTextureClientOGL(mTextureFlags);
   210     buffer->InitWith(data->mHandle, size, data->mShareType, data->mInverted);
   211     mFrontBuffer = buffer;
   212     if (!AddTextureClient(mFrontBuffer)) {
   213       mFrontBuffer = nullptr;
   214       return false;
   215     }
   217     GetForwarder()->UseTexture(this, mFrontBuffer);
   218   } else {
   219     RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface();
   220     MOZ_ASSERT(surface);
   222     gfx::IntSize size = image->GetSize();
   224     if (mFrontBuffer &&
   225         (mFrontBuffer->IsImmutable() || mFrontBuffer->GetSize() != size)) {
   226       GetForwarder()->RemoveTextureFromCompositable(this, mFrontBuffer);
   227       mFrontBuffer = nullptr;
   228     }
   230     bool bufferCreated = false;
   231     if (!mFrontBuffer) {
   232       gfxImageFormat format
   233         = gfxPlatform::GetPlatform()->OptimalFormatForContent(gfx::ContentForFormat(surface->GetFormat()));
   234       mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format),
   235                                                    mTextureFlags, gfx::BackendType::NONE, size);
   236       MOZ_ASSERT(mFrontBuffer->CanExposeDrawTarget());
   237       if (!mFrontBuffer->AllocateForSurface(size)) {
   238         mFrontBuffer = nullptr;
   239         return false;
   240       }
   242       bufferCreated = true;
   243     }
   245     if (!mFrontBuffer->Lock(OPEN_WRITE_ONLY)) {
   246       mFrontBuffer = nullptr;
   247       return false;
   248     }
   250     {
   251       // We must not keep a reference to the DrawTarget after it has been unlocked.
   252       RefPtr<DrawTarget> dt = mFrontBuffer->GetAsDrawTarget();
   253       MOZ_ASSERT(surface.get());
   254       dt->CopySurface(surface, IntRect(IntPoint(), surface->GetSize()), IntPoint());
   255     }
   257     mFrontBuffer->Unlock();
   259     if (bufferCreated) {
   260       if (!AddTextureClient(mFrontBuffer)) {
   261         mFrontBuffer = nullptr;
   262         return false;
   263       }
   264     }
   266     GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr);
   267     GetForwarder()->UseTexture(this, mFrontBuffer);
   268   }
   270   UpdatePictureRect(image->GetPictureRect());
   272   mLastPaintedImageSerial = image->GetSerial();
   273   aContainer->NotifyPaintedImage(image);
   274   *aIsSwapped = true;
   275   return true;
   276 }
   278 bool
   279 ImageClientBuffered::UpdateImage(ImageContainer* aContainer,
   280                                  uint32_t aContentFlags)
   281 {
   282   RefPtr<TextureClient> temp = mFrontBuffer;
   283   mFrontBuffer = mBackBuffer;
   284   mBackBuffer = temp;
   286   bool isSwapped = false;
   287   bool ret = ImageClientSingle::UpdateImageInternal(aContainer, aContentFlags, &isSwapped);
   289   if (!isSwapped) {
   290     // If buffer swap did not happen at Host side, swap back the buffers.
   291     RefPtr<TextureClient> temp = mFrontBuffer;
   292     mFrontBuffer = mBackBuffer;
   293     mBackBuffer = temp;
   294   }
   295   return ret;
   296 }
   298 bool
   299 ImageClientSingle::AddTextureClient(TextureClient* aTexture)
   300 {
   301   MOZ_ASSERT((mTextureFlags & aTexture->GetFlags()) == mTextureFlags);
   302   return CompositableClient::AddTextureClient(aTexture);
   303 }
   305 void
   306 ImageClientSingle::OnDetach()
   307 {
   308   mFrontBuffer = nullptr;
   309 }
   311 void
   312 ImageClientBuffered::OnDetach()
   313 {
   314   mFrontBuffer = nullptr;
   315   mBackBuffer = nullptr;
   316 }
   318 ImageClient::ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
   319                          CompositableType aType)
   320 : CompositableClient(aFwd, aFlags)
   321 , mType(aType)
   322 , mLastPaintedImageSerial(0)
   323 {}
   325 void
   326 ImageClient::UpdatePictureRect(nsIntRect aRect)
   327 {
   328   if (mPictureRect == aRect) {
   329     return;
   330   }
   331   mPictureRect = aRect;
   332   MOZ_ASSERT(mForwarder);
   333   GetForwarder()->UpdatePictureRect(this, aRect);
   334 }
   336 ImageClientBridge::ImageClientBridge(CompositableForwarder* aFwd,
   337                                      TextureFlags aFlags)
   338 : ImageClient(aFwd, aFlags, BUFFER_BRIDGE)
   339 , mAsyncContainerID(0)
   340 , mLayer(nullptr)
   341 {
   342 }
   344 bool
   345 ImageClientBridge::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags)
   346 {
   347   if (!GetForwarder() || !mLayer) {
   348     return false;
   349   }
   350   if (mAsyncContainerID == aContainer->GetAsyncContainerID()) {
   351     return true;
   352   }
   353   mAsyncContainerID = aContainer->GetAsyncContainerID();
   354   static_cast<ShadowLayerForwarder*>(GetForwarder())->AttachAsyncCompositable(mAsyncContainerID, mLayer);
   355   AutoLockImage autoLock(aContainer);
   356   aContainer->NotifyPaintedImage(autoLock.GetImage());
   357   Updated();
   358   return true;
   359 }
   361 already_AddRefed<Image>
   362 ImageClientSingle::CreateImage(ImageFormat aFormat)
   363 {
   364   nsRefPtr<Image> img;
   365   switch (aFormat) {
   366     case ImageFormat::PLANAR_YCBCR:
   367       img = new SharedPlanarYCbCrImage(this);
   368       return img.forget();
   369     case ImageFormat::SHARED_RGB:
   370       img = new SharedRGBImage(this);
   371       return img.forget();
   372 #ifdef MOZ_WIDGET_GONK
   373     case ImageFormat::GRALLOC_PLANAR_YCBCR:
   374       img = new GrallocImage();
   375       return img.forget();
   376 #endif
   377     default:
   378       return nullptr;
   379   }
   380 }
   382 }
   383 }

mercurial