LCOV - code coverage report
Current view: top level - gfx/layers/mlgpu - MLGDevice.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 158 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 24 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 "MLGDevice.h"
       7             : #include "mozilla/layers/TextureHost.h"
       8             : #include "BufferCache.h"
       9             : #include "ClearRegionHelper.h"
      10             : #include "gfxConfig.h"
      11             : #include "gfxPrefs.h"
      12             : #include "gfxUtils.h"
      13             : #include "ShaderDefinitionsMLGPU.h"
      14             : #include "SharedBufferMLGPU.h"
      15             : 
      16             : namespace mozilla {
      17             : namespace layers {
      18             : 
      19             : using namespace gfx;
      20             : using namespace mlg;
      21             : 
      22           0 : MLGRenderTarget::MLGRenderTarget(MLGRenderTargetFlags aFlags)
      23             :  : mFlags(aFlags),
      24           0 :    mLastDepthStart(-1)
      25             : {
      26           0 : }
      27             : 
      28           0 : MLGSwapChain::MLGSwapChain()
      29           0 :  : mIsDoubleBuffered(false)
      30             : {
      31           0 : }
      32             : 
      33             : bool
      34           0 : MLGSwapChain::ApplyNewInvalidRegion(nsIntRegion&& aRegion, const Maybe<gfx::IntRect>& aExtraRect)
      35             : {
      36             :   // We clamp the invalid region to the backbuffer size, otherwise the present
      37             :   // can fail.
      38           0 :   IntRect bounds(IntPoint(0, 0), GetSize());
      39           0 :   nsIntRegion invalid = Move(aRegion);
      40           0 :   invalid.AndWith(bounds);
      41           0 :   if (invalid.IsEmpty()) {
      42           0 :     return false;
      43             :   }
      44             : 
      45           0 :   if (aExtraRect) {
      46           0 :     IntRect rect = aExtraRect.value().Intersect(bounds);
      47           0 :     if (!rect.IsEmpty()) {
      48           0 :       invalid.OrWith(rect);
      49             :     }
      50             :   }
      51             : 
      52             :   // This area is now invalid in the back and front buffers. Note that the front
      53             :   // buffer is either totally valid or totally invalid, since either the last
      54             :   // paint succeeded or was thrown out due to a buffer resize. Effectively, it
      55             :   // will now contain the invalid region specific to this frame.
      56           0 :   mBackBufferInvalid.OrWith(invalid);
      57             :   AL_LOG("Backbuffer invalid region: %s\n", Stringify(mBackBufferInvalid).c_str());
      58             : 
      59           0 :   if (mIsDoubleBuffered) {
      60           0 :     mFrontBufferInvalid.OrWith(invalid);
      61             :     AL_LOG("Frontbuffer invalid region: %s\n", Stringify(mFrontBufferInvalid).c_str());
      62             :   }
      63           0 :   return true;
      64             : }
      65             : 
      66           0 : MLGDevice::MLGDevice()
      67             :  : mTopology(MLGPrimitiveTopology::Unknown),
      68             :    mIsValid(false),
      69             :    mCanUseClearView(false),
      70             :    mCanUseConstantBufferOffsetBinding(false),
      71           0 :    mMaxConstantBufferBindSize(0)
      72             : {
      73           0 : }
      74             : 
      75           0 : MLGDevice::~MLGDevice()
      76             : {
      77           0 : }
      78             : 
      79             : bool
      80           0 : MLGDevice::Initialize()
      81             : {
      82           0 :   if (!mMaxConstantBufferBindSize) {
      83           0 :     return Fail("FEATURE_FAILURE_NO_MAX_CB_BIND_SIZE", "Failed to set a max constant buffer bind size");
      84             :   }
      85           0 :   if (mMaxConstantBufferBindSize < mlg::kMaxConstantBufferSize) {
      86             :     // StagingBuffer depends on this value being accurate, so for now we just
      87             :     // double-check it here.
      88           0 :     return Fail("FEATURE_FAILURE_MIN_MAX_CB_BIND_SIZE", "Minimum constant buffer bind size not met");
      89             :   }
      90             : 
      91             :   // We allow this to be pref'd off for testing. Switching it off enables
      92             :   // Direct3D 11.0/Windows 7/OpenGL-style buffer code paths.
      93           0 :   if (!gfxPrefs::AdvancedLayersEnableBufferSharing()) {
      94             :     gfxConfig::EnableFallback(Fallback::NO_CONSTANT_BUFFER_OFFSETTING,
      95           0 :                               "Disabled by pref");
      96           0 :     mCanUseConstantBufferOffsetBinding = false;
      97             :   }
      98           0 :   if (mCanUseConstantBufferOffsetBinding && !VerifyConstantBufferOffsetting()) {
      99             :     gfxConfig::EnableFallback(Fallback::NO_CONSTANT_BUFFER_OFFSETTING,
     100           0 :                               "Constant buffer offset binding does not work");
     101           0 :     mCanUseConstantBufferOffsetBinding = false;
     102             :   }
     103             : 
     104             :   // We allow this to be pref'd off for testing. Disabling it turns on
     105             :   // ID3D11DeviceContext1::ClearView support, which is present on
     106             :   // newer Windows 8+ drivers.
     107           0 :   if (!gfxPrefs::AdvancedLayersEnableClearView()) {
     108           0 :     mCanUseClearView = false;
     109             :   }
     110             : 
     111             :   // When compositing normal sized layer trees, we typically have small vertex
     112             :   // buffers. Empirically the vertex and pixel constant buffer sizes are generally
     113             :   // under 1KB and the vertex constant buffer size is under 8KB.
     114             :   static const size_t kDefaultVertexBufferSize = 4096;
     115             :   static const size_t kDefaultVSConstantBufferSize = 512 * kConstantBufferElementSize;
     116             :   static const size_t kDefaultPSConstantBufferSize = 256 * kConstantBufferElementSize;
     117             : 
     118             :   // Note: we create these after we've verified all the device-specific properties above.
     119           0 :   mSharedVertexBuffer = MakeUnique<SharedVertexBuffer>(this, kDefaultVertexBufferSize);
     120           0 :   mSharedVSBuffer = MakeUnique<SharedConstantBuffer>(this, kDefaultVSConstantBufferSize);
     121           0 :   mSharedPSBuffer = MakeUnique<SharedConstantBuffer>(this, kDefaultPSConstantBufferSize);
     122             : 
     123           0 :   if (!mSharedVertexBuffer->Init() ||
     124           0 :       !mSharedVSBuffer->Init() ||
     125           0 :       !mSharedPSBuffer->Init())
     126             :   {
     127           0 :     return Fail("FEATURE_FAILURE_ALLOC_SHARED_BUFFER", "Failed to allocate a shared shader buffer");
     128             :   }
     129             : 
     130           0 :   if (gfxPrefs::AdvancedLayersEnableBufferCache()) {
     131           0 :     mConstantBufferCache = MakeUnique<BufferCache>(this);
     132             :   }
     133             : 
     134           0 :   mInitialized = true;
     135           0 :   mIsValid = true;
     136           0 :   return true;
     137             : }
     138             : 
     139             : void
     140           0 : MLGDevice::BeginFrame()
     141             : {
     142           0 :   mSharedVertexBuffer->Reset();
     143           0 :   mSharedPSBuffer->Reset();
     144           0 :   mSharedVSBuffer->Reset();
     145           0 : }
     146             : 
     147             : void
     148           0 : MLGDevice::EndFrame()
     149             : {
     150           0 :   if (mConstantBufferCache) {
     151           0 :     mConstantBufferCache->EndFrame();
     152             :   }
     153           0 : }
     154             : 
     155             : void
     156           0 : MLGDevice::FinishSharedBufferUse()
     157             : {
     158           0 :   mSharedVertexBuffer->PrepareForUsage();
     159           0 :   mSharedPSBuffer->PrepareForUsage();
     160           0 :   mSharedVSBuffer->PrepareForUsage();
     161           0 : }
     162             : 
     163             : void
     164           0 : MLGDevice::SetTopology(MLGPrimitiveTopology aTopology)
     165             : {
     166           0 :   if (mTopology == aTopology) {
     167           0 :     return;
     168             :   }
     169           0 :   SetPrimitiveTopology(aTopology);
     170           0 :   mTopology = aTopology;
     171             : }
     172             : 
     173             : void
     174           0 : MLGDevice::SetVertexBuffer(uint32_t aSlot, const VertexBufferSection* aSection)
     175             : {
     176           0 :   if (!aSection->IsValid()) {
     177           0 :     return;
     178             :   }
     179           0 :   SetVertexBuffer(aSlot, aSection->GetBuffer(), aSection->Stride(), aSection->Offset());
     180             : }
     181             : 
     182             : void
     183           0 : MLGDevice::SetPSConstantBuffer(uint32_t aSlot, const ConstantBufferSection* aSection)
     184             : {
     185           0 :   if (!aSection->IsValid()) {
     186           0 :     return;
     187             :   }
     188             : 
     189           0 :   MLGBuffer* buffer = aSection->GetBuffer();
     190             : 
     191           0 :   if (aSection->HasOffset()) {
     192           0 :     uint32_t first = aSection->Offset();
     193           0 :     uint32_t numConstants = aSection->NumConstants();
     194           0 :     SetPSConstantBuffer(aSlot, buffer, first, numConstants);
     195             :   } else {
     196           0 :     SetPSConstantBuffer(aSlot, buffer);
     197             :   }
     198             : }
     199             : 
     200             : void
     201           0 : MLGDevice::SetVSConstantBuffer(uint32_t aSlot, const ConstantBufferSection* aSection)
     202             : {
     203           0 :   if (!aSection->IsValid()) {
     204           0 :     return;
     205             :   }
     206             : 
     207           0 :   MLGBuffer* buffer = aSection->GetBuffer();
     208             : 
     209           0 :   if (aSection->HasOffset()) {
     210           0 :     uint32_t first = aSection->Offset();
     211           0 :     uint32_t numConstants = aSection->NumConstants();
     212           0 :     SetVSConstantBuffer(aSlot, buffer, first, numConstants);
     213             :   } else {
     214           0 :     SetVSConstantBuffer(aSlot, buffer);
     215             :   }
     216             : }
     217             : 
     218             : void
     219           0 : MLGDevice::SetPSTexturesYUV(uint32_t aSlot, TextureSource* aTexture)
     220             : {
     221             :   // Note, we don't support tiled YCbCr textures.
     222           0 :   const int Y = 0, Cb = 1, Cr = 2;
     223             :   TextureSource* textures[3] = {
     224           0 :     aTexture->GetSubSource(Y),
     225           0 :     aTexture->GetSubSource(Cb),
     226           0 :     aTexture->GetSubSource(Cr)
     227           0 :   };
     228           0 :   MOZ_ASSERT(textures[0]);
     229           0 :   MOZ_ASSERT(textures[1]);
     230           0 :   MOZ_ASSERT(textures[2]);
     231             : 
     232           0 :   SetPSTextures(0, 3, textures);
     233           0 : }
     234             : 
     235             : void
     236           0 : MLGDevice::SetPSTexture(uint32_t aSlot, TextureSource* aSource)
     237             : {
     238           0 :   SetPSTextures(aSlot, 1, &aSource);
     239           0 : }
     240             : 
     241             : static inline SamplerMode
     242           0 : FilterToSamplerMode(gfx::SamplingFilter aFilter)
     243             : {
     244           0 :   switch (aFilter) {
     245             :   case gfx::SamplingFilter::POINT:
     246           0 :     return SamplerMode::Point;
     247             :   case gfx::SamplingFilter::LINEAR:
     248             :   case gfx::SamplingFilter::GOOD:
     249           0 :     return SamplerMode::LinearClamp;
     250             :   default:
     251           0 :     MOZ_ASSERT_UNREACHABLE("Unknown sampler mode");
     252             :     return SamplerMode::LinearClamp;
     253             :   }
     254             : }
     255             : 
     256             : void
     257           0 : MLGDevice::SetSamplerMode(uint32_t aIndex, gfx::SamplingFilter aFilter)
     258             : {
     259           0 :   SetSamplerMode(aIndex, FilterToSamplerMode(aFilter));
     260           0 : }
     261             : 
     262             : bool
     263           0 : MLGDevice::Fail(const nsCString& aFailureId, const nsCString* aMessage)
     264             : {
     265             :   const char* message = aMessage
     266           0 :                         ? aMessage->get()
     267           0 :                         : "Failed initializing MLGDeviceD3D11";
     268           0 :   gfxWarning() << "Failure initializing MLGDeviceD3D11: " << message;
     269           0 :   mFailureId = aFailureId;
     270           0 :   mFailureMessage = message;
     271           0 :   return false;
     272             : }
     273             : 
     274             : void
     275           0 : MLGDevice::UnmapSharedBuffers()
     276             : {
     277           0 :   mSharedVertexBuffer->Reset();
     278           0 :   mSharedPSBuffer->Reset();
     279           0 :   mSharedVSBuffer->Reset();
     280           0 : }
     281             : 
     282             : RefPtr<MLGBuffer>
     283           0 : MLGDevice::GetBufferForColorSpace(YUVColorSpace aColorSpace)
     284             : {
     285           0 :   if (mColorSpaceBuffers[aColorSpace]) {
     286           0 :     return mColorSpaceBuffers[aColorSpace];
     287             :   }
     288             : 
     289             :   YCbCrShaderConstants buffer;
     290             :   memcpy(
     291             :     &buffer.yuvColorMatrix,
     292           0 :     gfxUtils::YuvToRgbMatrix4x3RowMajor(aColorSpace),
     293           0 :     sizeof(buffer.yuvColorMatrix));
     294             : 
     295             :   RefPtr<MLGBuffer> resource = CreateBuffer(
     296             :     MLGBufferType::Constant,
     297             :     sizeof(buffer),
     298             :     MLGUsage::Immutable,
     299           0 :     &buffer);
     300           0 :   if (!resource) {
     301           0 :     return nullptr;
     302             :   }
     303             : 
     304           0 :   mColorSpaceBuffers[aColorSpace] = resource;
     305           0 :   return resource;
     306             : }
     307             : 
     308             : bool
     309           0 : MLGDevice::Synchronize()
     310             : {
     311           0 :   return true;
     312             : }
     313             : 
     314             : void
     315           0 : MLGDevice::PrepareClearRegion(ClearRegionHelper* aOut,
     316             :                               nsTArray<gfx::IntRect>&& aRects,
     317             :                               const Maybe<int32_t>& aSortIndex)
     318             : {
     319           0 :   if (CanUseClearView() && !aSortIndex) {
     320           0 :     aOut->mRects = Move(aRects);
     321           0 :     return;
     322             :   }
     323             : 
     324           0 :   mSharedVertexBuffer->Allocate(
     325             :     &aOut->mInput,
     326             :     aRects.Length(),
     327             :     sizeof(IntRect),
     328           0 :     aRects.Elements());
     329             : 
     330           0 :   ClearConstants consts(aSortIndex ? aSortIndex.value() : 1);
     331           0 :   mSharedVSBuffer->Allocate(&aOut->mVSBuffer, consts);
     332             : }
     333             : 
     334             : void
     335           0 : MLGDevice::DrawClearRegion(const ClearRegionHelper& aHelper)
     336             : {
     337             :   // If we've set up vertices for a shader-based clear, execute that now.
     338           0 :   if (aHelper.mInput.IsValid()) {
     339           0 :     SetTopology(MLGPrimitiveTopology::UnitQuad);
     340           0 :     SetVertexShader(VertexShaderID::Clear);
     341           0 :     SetVertexBuffer(1, &aHelper.mInput);
     342           0 :     SetVSConstantBuffer(kClearConstantBufferSlot, &aHelper.mVSBuffer);
     343           0 :     SetBlendState(MLGBlendState::Copy);
     344           0 :     SetPixelShader(PixelShaderID::Clear);
     345           0 :     DrawInstanced(4, aHelper.mInput.NumVertices(), 0, 0);
     346           0 :     return;
     347             :   }
     348             : 
     349             :   // Otherwise, if we have a normal rect list, we wanted to use the faster
     350             :   // ClearView.
     351           0 :   if (!aHelper.mRects.IsEmpty()) {
     352           0 :     Color color(0.0, 0.0, 0.0, 0.0);
     353           0 :     ClearView(mCurrentRT, color, aHelper.mRects.Elements(), aHelper.mRects.Length());
     354             :   }
     355             : }
     356             : 
     357             : } // namespace layers
     358             : } // namespace mozilla

Generated by: LCOV version 1.13