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

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "AsyncCanvasRenderer.h"
       8             : 
       9             : #include "gfxUtils.h"
      10             : #include "GLContext.h"
      11             : #include "GLReadTexImageHelper.h"
      12             : #include "GLScreenBuffer.h"
      13             : #include "mozilla/dom/HTMLCanvasElement.h"
      14             : #include "mozilla/layers/BufferTexture.h"
      15             : #include "mozilla/layers/CanvasClient.h"
      16             : #include "mozilla/layers/TextureClient.h"
      17             : #include "mozilla/layers/TextureClientSharedSurface.h"
      18             : #include "mozilla/ReentrantMonitor.h"
      19             : #include "nsIRunnable.h"
      20             : #include "nsThreadUtils.h"
      21             : 
      22             : namespace mozilla {
      23             : namespace layers {
      24             : 
      25           0 : AsyncCanvasRenderer::AsyncCanvasRenderer()
      26             :   : mHTMLCanvasElement(nullptr)
      27             :   , mContext(nullptr)
      28             :   , mGLContext(nullptr)
      29             :   , mIsAlphaPremultiplied(true)
      30             :   , mWidth(0)
      31             :   , mHeight(0)
      32             :   , mCanvasClient(nullptr)
      33           0 :   , mMutex("AsyncCanvasRenderer::mMutex")
      34             : {
      35           0 :   MOZ_COUNT_CTOR(AsyncCanvasRenderer);
      36           0 : }
      37             : 
      38           0 : AsyncCanvasRenderer::~AsyncCanvasRenderer()
      39             : {
      40           0 :   MOZ_COUNT_DTOR(AsyncCanvasRenderer);
      41           0 : }
      42             : 
      43             : void
      44           0 : AsyncCanvasRenderer::NotifyElementAboutAttributesChanged()
      45             : {
      46           0 :   class Runnable final : public mozilla::Runnable
      47             :   {
      48             :   public:
      49           0 :     explicit Runnable(AsyncCanvasRenderer* aRenderer)
      50           0 :       : mozilla::Runnable("Runnable")
      51           0 :       , mRenderer(aRenderer)
      52           0 :     {}
      53             : 
      54           0 :     NS_IMETHOD Run() override
      55             :     {
      56           0 :       if (mRenderer) {
      57           0 :         dom::HTMLCanvasElement::SetAttrFromAsyncCanvasRenderer(mRenderer);
      58             :       }
      59             : 
      60           0 :       return NS_OK;
      61             :     }
      62             : 
      63             :   private:
      64             :     RefPtr<AsyncCanvasRenderer> mRenderer;
      65             :   };
      66             : 
      67           0 :   nsCOMPtr<nsIRunnable> runnable = new Runnable(this);
      68           0 :   nsresult rv = NS_DispatchToMainThread(runnable);
      69           0 :   if (NS_FAILED(rv)) {
      70           0 :     NS_WARNING("Failed to dispatch a runnable to the main-thread.");
      71             :   }
      72           0 : }
      73             : 
      74             : void
      75           0 : AsyncCanvasRenderer::NotifyElementAboutInvalidation()
      76             : {
      77           0 :   class Runnable final : public mozilla::Runnable
      78             :   {
      79             :   public:
      80           0 :     explicit Runnable(AsyncCanvasRenderer* aRenderer)
      81           0 :       : mozilla::Runnable("Runnable")
      82           0 :       , mRenderer(aRenderer)
      83           0 :     {}
      84             : 
      85           0 :     NS_IMETHOD Run() override
      86             :     {
      87           0 :       if (mRenderer) {
      88           0 :         dom::HTMLCanvasElement::InvalidateFromAsyncCanvasRenderer(mRenderer);
      89             :       }
      90             : 
      91           0 :       return NS_OK;
      92             :     }
      93             : 
      94             :   private:
      95             :     RefPtr<AsyncCanvasRenderer> mRenderer;
      96             :   };
      97             : 
      98           0 :   nsCOMPtr<nsIRunnable> runnable = new Runnable(this);
      99           0 :   nsresult rv = NS_DispatchToMainThread(runnable);
     100           0 :   if (NS_FAILED(rv)) {
     101           0 :     NS_WARNING("Failed to dispatch a runnable to the main-thread.");
     102             :   }
     103           0 : }
     104             : 
     105             : void
     106           0 : AsyncCanvasRenderer::SetCanvasClient(CanvasClient* aClient)
     107             : {
     108           0 :   mCanvasClient = aClient;
     109           0 :   if (aClient) {
     110           0 :     mCanvasClientAsyncHandle = aClient->GetAsyncHandle();
     111             :   } else {
     112           0 :     mCanvasClientAsyncHandle = CompositableHandle();
     113             :   }
     114           0 : }
     115             : 
     116             : void
     117           0 : AsyncCanvasRenderer::SetActiveEventTarget()
     118             : {
     119           0 :   MutexAutoLock lock(mMutex);
     120           0 :   mActiveEventTarget = GetCurrentThreadSerialEventTarget();
     121           0 : }
     122             : 
     123             : void
     124           0 : AsyncCanvasRenderer::ResetActiveEventTarget()
     125             : {
     126           0 :   MutexAutoLock lock(mMutex);
     127           0 :   mActiveEventTarget = nullptr;
     128           0 : }
     129             : 
     130             : already_AddRefed<nsISerialEventTarget>
     131           0 : AsyncCanvasRenderer::GetActiveEventTarget()
     132             : {
     133           0 :   MutexAutoLock lock(mMutex);
     134           0 :   nsCOMPtr<nsISerialEventTarget> result = mActiveEventTarget;
     135           0 :   return result.forget();
     136             : }
     137             : 
     138             : void
     139           0 : AsyncCanvasRenderer::CopyFromTextureClient(TextureClient* aTextureClient)
     140             : {
     141           0 :   MutexAutoLock lock(mMutex);
     142             : 
     143           0 :   if (!aTextureClient) {
     144           0 :     mSurfaceForBasic = nullptr;
     145           0 :     return;
     146             :   }
     147             : 
     148           0 :   TextureClientAutoLock texLock(aTextureClient, layers::OpenMode::OPEN_READ);
     149           0 :   if (!texLock.Succeeded()) {
     150           0 :     return;
     151             :   }
     152             : 
     153           0 :   const gfx::IntSize& size = aTextureClient->GetSize();
     154             :   // This buffer would be used later for content rendering. So we choose
     155             :   // B8G8R8A8 format here.
     156           0 :   const gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8;
     157             :   // Avoid to create buffer every time.
     158           0 :   if (!mSurfaceForBasic ||
     159           0 :       size != mSurfaceForBasic->GetSize() ||
     160           0 :       format != mSurfaceForBasic->GetFormat())
     161             :   {
     162           0 :     uint32_t stride = gfx::GetAlignedStride<8>(size.width, BytesPerPixel(format));
     163           0 :     mSurfaceForBasic = gfx::Factory::CreateDataSourceSurfaceWithStride(size, format, stride);
     164             :   }
     165             : 
     166           0 :   MappedTextureData mapped;
     167           0 :   if (!aTextureClient->BorrowMappedData(mapped)) {
     168           0 :     return;
     169             :   }
     170             : 
     171           0 :   const uint8_t* lockedBytes = mapped.data;
     172             :   gfx::DataSourceSurface::ScopedMap map(mSurfaceForBasic,
     173           0 :                                         gfx::DataSourceSurface::MapType::WRITE);
     174           0 :   if (!map.IsMapped()) {
     175           0 :     return;
     176             :   }
     177             : 
     178           0 :   MOZ_ASSERT(map.GetStride() == mapped.stride);
     179           0 :   memcpy(map.GetData(), lockedBytes, map.GetStride() * mSurfaceForBasic->GetSize().height);
     180             : 
     181           0 :   if (mSurfaceForBasic->GetFormat() == gfx::SurfaceFormat::R8G8B8A8 ||
     182           0 :       mSurfaceForBasic->GetFormat() == gfx::SurfaceFormat::R8G8B8X8) {
     183           0 :     gl::SwapRAndBComponents(mSurfaceForBasic);
     184             :   }
     185             : }
     186             : 
     187             : already_AddRefed<gfx::DataSourceSurface>
     188           0 : AsyncCanvasRenderer::UpdateTarget()
     189             : {
     190           0 :   if (!mGLContext) {
     191           0 :     return nullptr;
     192             :   }
     193             : 
     194           0 :   gl::SharedSurface* frontbuffer = nullptr;
     195           0 :   gl::GLScreenBuffer* screen = mGLContext->Screen();
     196           0 :   const auto& front = screen->Front();
     197           0 :   if (front) {
     198           0 :     frontbuffer = front->Surf();
     199             :   }
     200             : 
     201           0 :   if (!frontbuffer) {
     202           0 :     return nullptr;
     203             :   }
     204             : 
     205           0 :   if (frontbuffer->mType == gl::SharedSurfaceType::Basic) {
     206           0 :     return nullptr;
     207             :   }
     208             : 
     209           0 :   const gfx::IntSize& size = frontbuffer->mSize;
     210             :   // This buffer would be used later for content rendering. So we choose
     211             :   // B8G8R8A8 format here.
     212           0 :   const gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8;
     213           0 :   uint32_t stride = gfx::GetAlignedStride<8>(size.width, BytesPerPixel(format));
     214             :   RefPtr<gfx::DataSourceSurface> surface =
     215           0 :     gfx::Factory::CreateDataSourceSurfaceWithStride(size, format, stride);
     216             : 
     217             : 
     218           0 :   if (NS_WARN_IF(!surface)) {
     219           0 :     return nullptr;
     220             :   }
     221             : 
     222           0 :   if (!frontbuffer->ReadbackBySharedHandle(surface)) {
     223           0 :     return nullptr;
     224             :   }
     225             : 
     226           0 :   bool needsPremult = frontbuffer->mHasAlpha && !mIsAlphaPremultiplied;
     227           0 :   if (needsPremult) {
     228           0 :     gfxUtils::PremultiplyDataSurface(surface, surface);
     229             :   }
     230             : 
     231           0 :   return surface.forget();
     232             : }
     233             : 
     234             : already_AddRefed<gfx::DataSourceSurface>
     235           0 : AsyncCanvasRenderer::GetSurface()
     236             : {
     237           0 :   MOZ_ASSERT(NS_IsMainThread());
     238           0 :   MutexAutoLock lock(mMutex);
     239           0 :   if (mSurfaceForBasic) {
     240             :     // Since SourceSurface isn't thread-safe, we need copy to a new SourceSurface.
     241             :     RefPtr<gfx::DataSourceSurface> result =
     242           0 :       gfx::Factory::CreateDataSourceSurfaceWithStride(mSurfaceForBasic->GetSize(),
     243           0 :                                                       mSurfaceForBasic->GetFormat(),
     244           0 :                                                       mSurfaceForBasic->Stride());
     245             : 
     246           0 :     gfx::DataSourceSurface::ScopedMap srcMap(mSurfaceForBasic, gfx::DataSourceSurface::READ);
     247           0 :     gfx::DataSourceSurface::ScopedMap dstMap(result, gfx::DataSourceSurface::WRITE);
     248             : 
     249           0 :     if (NS_WARN_IF(!srcMap.IsMapped()) ||
     250           0 :         NS_WARN_IF(!dstMap.IsMapped())) {
     251           0 :       return nullptr;
     252             :     }
     253             : 
     254           0 :     memcpy(dstMap.GetData(),
     255           0 :            srcMap.GetData(),
     256           0 :            srcMap.GetStride() * mSurfaceForBasic->GetSize().height);
     257           0 :     return result.forget();
     258             :   } else {
     259           0 :     return UpdateTarget();
     260             :   }
     261             : }
     262             : 
     263             : nsresult
     264           0 : AsyncCanvasRenderer::GetInputStream(const char *aMimeType,
     265             :                                     const char16_t *aEncoderOptions,
     266             :                                     nsIInputStream **aStream)
     267             : {
     268           0 :   MOZ_ASSERT(NS_IsMainThread());
     269           0 :   RefPtr<gfx::DataSourceSurface> surface = GetSurface();
     270           0 :   if (!surface) {
     271           0 :     return NS_ERROR_FAILURE;
     272             :   }
     273             : 
     274             :   // Handle y flip.
     275           0 :   RefPtr<gfx::DataSourceSurface> dataSurf = gl::YInvertImageSurface(surface);
     276             : 
     277           0 :   return gfxUtils::GetInputStream(dataSurf, false, aMimeType, aEncoderOptions, aStream);
     278             : }
     279             : 
     280             : } // namespace layers
     281             : } // namespace mozilla

Generated by: LCOV version 1.13