mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Add a helper for automating ClearView and clear-shader operations. (bug 1378095 part 1, r=mattwoodrow)
This commit is contained in:
parent
d11ba73bee
commit
ddfbc3d0ae
@ -304,7 +304,6 @@ private:
|
||||
RefPtr<IDXGIResource> mSyncTexture;
|
||||
HANDLE mSyncHandle;
|
||||
|
||||
RefPtr<MLGRenderTarget> mCurrentRT;
|
||||
RefPtr<MLGBuffer> mUnitQuadVB;
|
||||
RefPtr<MLGBuffer> mUnitTriangleVB;
|
||||
RefPtr<ID3D11VertexShader> mCurrentVertexShader;
|
||||
|
30
gfx/layers/mlgpu/ClearRegionHelper.h
Normal file
30
gfx/layers/mlgpu/ClearRegionHelper.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_gfx_layers_mlgpu_ClearRegionHelper_h
|
||||
#define mozilla_gfx_layers_mlgpu_ClearRegionHelper_h
|
||||
|
||||
#include "SharedBufferMLGPU.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// This is a helper class for issuing a clear operation based on either
|
||||
// a shader or an API like ClearView. It also works when the depth
|
||||
// buffer is enabled.
|
||||
struct ClearRegionHelper
|
||||
{
|
||||
// If using ClearView-based clears, we fill mRegions.
|
||||
nsTArray<gfx::IntRect> mRects;
|
||||
|
||||
// If using shader-based clears, we fill these buffers.
|
||||
VertexBufferSection mInput;
|
||||
ConstantBufferSection mVSBuffer;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_gfx_layers_mlgpu_ClearRegionHelper_h
|
@ -6,6 +6,7 @@
|
||||
#include "MLGDevice.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "BufferCache.h"
|
||||
#include "ClearRegionHelper.h"
|
||||
#include "gfxConfig.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "gfxUtils.h"
|
||||
@ -170,7 +171,7 @@ MLGDevice::SetTopology(MLGPrimitiveTopology aTopology)
|
||||
}
|
||||
|
||||
void
|
||||
MLGDevice::SetVertexBuffer(uint32_t aSlot, VertexBufferSection* aSection)
|
||||
MLGDevice::SetVertexBuffer(uint32_t aSlot, const VertexBufferSection* aSection)
|
||||
{
|
||||
if (!aSection->IsValid()) {
|
||||
return;
|
||||
@ -179,7 +180,7 @@ MLGDevice::SetVertexBuffer(uint32_t aSlot, VertexBufferSection* aSection)
|
||||
}
|
||||
|
||||
void
|
||||
MLGDevice::SetPSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection)
|
||||
MLGDevice::SetPSConstantBuffer(uint32_t aSlot, const ConstantBufferSection* aSection)
|
||||
{
|
||||
if (!aSection->IsValid()) {
|
||||
return;
|
||||
@ -197,7 +198,7 @@ MLGDevice::SetPSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection)
|
||||
}
|
||||
|
||||
void
|
||||
MLGDevice::SetVSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection)
|
||||
MLGDevice::SetVSConstantBuffer(uint32_t aSlot, const ConstantBufferSection* aSection)
|
||||
{
|
||||
if (!aSection->IsValid()) {
|
||||
return;
|
||||
@ -310,5 +311,48 @@ MLGDevice::Synchronize()
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MLGDevice::PrepareClearRegion(ClearRegionHelper* aOut,
|
||||
nsTArray<gfx::IntRect>&& aRects,
|
||||
const Maybe<int32_t>& aSortIndex)
|
||||
{
|
||||
if (CanUseClearView() && !aSortIndex) {
|
||||
aOut->mRects = Move(aRects);
|
||||
return;
|
||||
}
|
||||
|
||||
mSharedVertexBuffer->Allocate(
|
||||
&aOut->mInput,
|
||||
aRects.Length(),
|
||||
sizeof(IntRect),
|
||||
aRects.Elements());
|
||||
|
||||
ClearConstants consts(aSortIndex ? aSortIndex.value() : 1);
|
||||
mSharedVSBuffer->Allocate(&aOut->mVSBuffer, consts);
|
||||
}
|
||||
|
||||
void
|
||||
MLGDevice::DrawClearRegion(const ClearRegionHelper& aHelper)
|
||||
{
|
||||
// If we've set up vertices for a shader-based clear, execute that now.
|
||||
if (aHelper.mInput.IsValid()) {
|
||||
SetTopology(MLGPrimitiveTopology::UnitQuad);
|
||||
SetVertexShader(VertexShaderID::Clear);
|
||||
SetVertexBuffer(1, &aHelper.mInput);
|
||||
SetVSConstantBuffer(kClearConstantBufferSlot, &aHelper.mVSBuffer);
|
||||
SetBlendState(MLGBlendState::Copy);
|
||||
SetPixelShader(PixelShaderID::Clear);
|
||||
DrawInstanced(4, aHelper.mInput.NumVertices(), 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, if we have a normal rect list, we wanted to use the faster
|
||||
// ClearView.
|
||||
if (!aHelper.mRects.IsEmpty()) {
|
||||
Color color(0.0, 0.0, 0.0, 0.0);
|
||||
ClearView(mCurrentRT, color, aHelper.mRects.Elements(), aHelper.mRects.Length());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -45,6 +45,7 @@ class SharedVertexBuffer;
|
||||
class SharedConstantBuffer;
|
||||
class TextureSource;
|
||||
class VertexBufferSection;
|
||||
struct ClearRegionHelper;
|
||||
|
||||
class MLGRenderTarget
|
||||
{
|
||||
@ -349,9 +350,9 @@ public:
|
||||
virtual MLGDeviceD3D11* AsD3D11() { return nullptr; }
|
||||
|
||||
// Helpers.
|
||||
void SetVertexBuffer(uint32_t aSlot, VertexBufferSection* aSection);
|
||||
void SetPSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection);
|
||||
void SetVSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection);
|
||||
void SetVertexBuffer(uint32_t aSlot, const VertexBufferSection* aSection);
|
||||
void SetPSConstantBuffer(uint32_t aSlot, const ConstantBufferSection* aSection);
|
||||
void SetVSConstantBuffer(uint32_t aSlot, const ConstantBufferSection* aSection);
|
||||
void SetPSTexture(uint32_t aSlot, TextureSource* aSource);
|
||||
void SetSamplerMode(uint32_t aIndex, gfx::SamplingFilter aFilter);
|
||||
|
||||
@ -392,6 +393,14 @@ public:
|
||||
return mFailureMessage;
|
||||
}
|
||||
|
||||
// Prepare a clear-region operation to be run at a later time.
|
||||
void PrepareClearRegion(ClearRegionHelper* aOut,
|
||||
nsTArray<gfx::IntRect>&& aRects,
|
||||
const Maybe<int32_t>& aSortIndex);
|
||||
|
||||
// Execute a clear-region operation. This may change shader state.
|
||||
void DrawClearRegion(const ClearRegionHelper& aHelper);
|
||||
|
||||
// If supported, synchronize with the SyncObject given to clients.
|
||||
virtual bool Synchronize();
|
||||
|
||||
@ -475,6 +484,8 @@ protected:
|
||||
bool mCanUseClearView;
|
||||
bool mCanUseConstantBufferOffsetBinding;
|
||||
size_t mMaxConstantBufferBindSize;
|
||||
|
||||
RefPtr<MLGRenderTarget> mCurrentRT;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -400,7 +400,7 @@ RenderViewMLGPU::ExecuteRendering()
|
||||
|
||||
// Clear any pixels that are not occluded, and therefore might require
|
||||
// blending.
|
||||
DrawClear();
|
||||
mDevice->DrawClearRegion(mClear);
|
||||
|
||||
// Render back-to-front passes.
|
||||
for (auto iter = mBackToFront.begin(); iter != mBackToFront.end(); iter++) {
|
||||
@ -498,51 +498,16 @@ RenderViewMLGPU::PrepareClear()
|
||||
region.SubOut(mOccludedRegion);
|
||||
region.SimplifyOutward(kMaxClearViewRects);
|
||||
}
|
||||
for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) {
|
||||
mClearRects.AppendElement(iter.Get().ToUnknownRect());
|
||||
|
||||
Maybe<int32_t> sortIndex;
|
||||
if (mUseDepthBuffer) {
|
||||
// Note that we use the lowest available sorting index, to ensure that when
|
||||
// using the z-buffer, we don't draw over already-drawn content.
|
||||
sortIndex = Some(mNextSortIndex++);
|
||||
}
|
||||
|
||||
// If ClearView is supported and we're not using a depth buffer, we
|
||||
// can stop here. We'll use the rects as inputs to ClearView.
|
||||
if (mClearRects.IsEmpty() || (mDevice->CanUseClearView() && !mUseDepthBuffer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up vertices for a shader-based clear.
|
||||
mDevice->GetSharedVertexBuffer()->Allocate(
|
||||
&mClearInput,
|
||||
mClearRects.Length(),
|
||||
sizeof(IntRect),
|
||||
mClearRects.Elements());
|
||||
mClearRects.Clear();
|
||||
|
||||
// Note that we use the lowest available sorting index, to ensure that when
|
||||
// using the z-buffer, we don't draw over already-drawn content.
|
||||
ClearConstants consts(mNextSortIndex++);
|
||||
mDevice->GetSharedVSBuffer()->Allocate(&mClearConstants, consts);
|
||||
}
|
||||
|
||||
void
|
||||
RenderViewMLGPU::DrawClear()
|
||||
{
|
||||
// If we've set up vertices for a shader-based clear, execute that now.
|
||||
if (mClearInput.IsValid()) {
|
||||
mDevice->SetTopology(MLGPrimitiveTopology::UnitQuad);
|
||||
mDevice->SetVertexShader(VertexShaderID::Clear);
|
||||
mDevice->SetVertexBuffer(1, &mClearInput);
|
||||
mDevice->SetVSConstantBuffer(kClearConstantBufferSlot, &mClearConstants);
|
||||
mDevice->SetBlendState(MLGBlendState::Copy);
|
||||
mDevice->SetPixelShader(PixelShaderID::Clear);
|
||||
mDevice->DrawInstanced(4, mClearInput.NumVertices(), 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, if we have a normal rect list, we wanted to use the faster
|
||||
// ClearView.
|
||||
if (!mClearRects.IsEmpty()) {
|
||||
Color color(0.0, 0.0, 0.0, 0.0);
|
||||
mDevice->ClearView(mTarget, color, mClearRects.Elements(), mClearRects.Length());
|
||||
}
|
||||
nsTArray<IntRect> rects = ToRectArray(region);
|
||||
mDevice->PrepareClearRegion(&mClear, Move(rects), sortIndex);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define mozilla_gfx_layers_mlgpu_RenderViewMLGPU_h
|
||||
|
||||
#include "LayerManagerMLGPU.h"
|
||||
#include "ClearRegionHelper.h"
|
||||
#include "RenderPassMLGPU.h"
|
||||
#include "Units.h"
|
||||
#include <deque>
|
||||
@ -90,12 +91,8 @@ private:
|
||||
// Shader data.
|
||||
ConstantBufferSection mWorldConstants;
|
||||
|
||||
// If using ClearView-based clears.
|
||||
nsTArray<gfx::IntRect> mClearRects;
|
||||
|
||||
// If using shader-based clears.
|
||||
VertexBufferSection mClearInput;
|
||||
ConstantBufferSection mClearConstants;
|
||||
// Information for the initial target surface clear.
|
||||
ClearRegionHelper mClear;
|
||||
|
||||
// Either an MLGSwapChain-derived render target, or an intermediate surface.
|
||||
RefPtr<MLGRenderTarget> mTarget;
|
||||
|
@ -95,6 +95,17 @@ struct BlendVertexShaderConstants {
|
||||
float backdropTransform[4][4];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static inline nsTArray<gfx::IntRect>
|
||||
ToRectArray(const T& aRegion)
|
||||
{
|
||||
nsTArray<gfx::IntRect> rects;
|
||||
for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
rects.AppendElement(iter.Get().ToUnknownRect());
|
||||
}
|
||||
return rects;
|
||||
}
|
||||
|
||||
struct SimpleTraits
|
||||
{
|
||||
explicit SimpleTraits(const ItemInfo& aItem, const gfx::Rect& aRect)
|
||||
|
Loading…
Reference in New Issue
Block a user