зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1677459 - Split platform independent part to RenderCompositorCompositorSWGL r=mattwoodrow
The change is a preparation of Bug 1673342 Differential Revision: https://phabricator.services.mozilla.com/D99046
This commit is contained in:
Родитель
6bd700d7de
Коммит
9d6fd76b93
|
@ -13,13 +13,13 @@
|
|||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/layers/SyncObject.h"
|
||||
#include "mozilla/webrender/RenderCompositorLayersSWGL.h"
|
||||
#include "mozilla/webrender/RenderCompositorOGL.h"
|
||||
#include "mozilla/webrender/RenderCompositorSWGL.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "mozilla/webrender/RenderCompositorANGLE.h"
|
||||
# include "mozilla/webrender/RenderCompositorD3D11SWGL.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_WAYLAND) || defined(MOZ_WIDGET_ANDROID)
|
||||
|
@ -155,16 +155,12 @@ UniquePtr<RenderCompositor> RenderCompositor::Create(
|
|||
if (!gfxPlatform::IsHeadless()) {
|
||||
return RenderCompositorNativeSWGL::Create(std::move(aWidget), aError);
|
||||
}
|
||||
#elif defined(XP_WIN)
|
||||
if (StaticPrefs::gfx_webrender_software_d3d11_AtStartup() &&
|
||||
gfx::gfxConfig::IsEnabled(gfx::Feature::D3D11_COMPOSITING)) {
|
||||
UniquePtr<RenderCompositor> comp =
|
||||
RenderCompositorD3D11SWGL::Create(std::move(aWidget), aError);
|
||||
if (comp) {
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
UniquePtr<RenderCompositor> comp =
|
||||
RenderCompositorLayersSWGL::Create(std::move(aWidget), aError);
|
||||
if (comp) {
|
||||
return comp;
|
||||
}
|
||||
return RenderCompositorSWGL::Create(std::move(aWidget), aError);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@ RenderCompositorD3D11SWGL::GetUploadMode() {
|
|||
|
||||
UniquePtr<RenderCompositor> RenderCompositorD3D11SWGL::Create(
|
||||
RefPtr<widget::CompositorWidget>&& aWidget, nsACString& aError) {
|
||||
if (!StaticPrefs::gfx_webrender_software_d3d11_AtStartup() ||
|
||||
!gfx::gfxConfig::IsEnabled(gfx::Feature::D3D11_COMPOSITING)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* ctx = wr_swgl_create_context();
|
||||
if (!ctx) {
|
||||
gfxCriticalNote << "Failed SWGL context creation for WebRender";
|
||||
|
@ -61,164 +66,88 @@ UniquePtr<RenderCompositor> RenderCompositorD3D11SWGL::Create(
|
|||
RenderCompositorD3D11SWGL::RenderCompositorD3D11SWGL(
|
||||
CompositorD3D11* aCompositor, RefPtr<widget::CompositorWidget>&& aWidget,
|
||||
void* aContext)
|
||||
: RenderCompositor(std::move(aWidget)),
|
||||
mCompositor(aCompositor),
|
||||
mContext(aContext) {
|
||||
MOZ_ASSERT(mContext);
|
||||
mSyncObject = mCompositor->GetSyncObject();
|
||||
: RenderCompositorLayersSWGL(aCompositor, std::move(aWidget), aContext) {
|
||||
mSyncObject = GetCompositorD3D11()->GetSyncObject();
|
||||
}
|
||||
|
||||
RenderCompositorD3D11SWGL::~RenderCompositorD3D11SWGL() {
|
||||
wr_swgl_destroy_context(mContext);
|
||||
}
|
||||
|
||||
bool RenderCompositorD3D11SWGL::MakeCurrent() {
|
||||
wr_swgl_make_current(mContext);
|
||||
return true;
|
||||
}
|
||||
RenderCompositorD3D11SWGL::~RenderCompositorD3D11SWGL() {}
|
||||
|
||||
bool RenderCompositorD3D11SWGL::BeginFrame() {
|
||||
MOZ_ASSERT(!mInFrame);
|
||||
MakeCurrent();
|
||||
IntRect rect = IntRect(IntPoint(0, 0), GetBufferSize().ToUnknownSize());
|
||||
if (!mCompositor->BeginFrameForWindow(nsIntRegion(rect), Nothing(), rect,
|
||||
nsIntRegion())) {
|
||||
if (!RenderCompositorLayersSWGL::BeginFrame()) {
|
||||
return false;
|
||||
}
|
||||
mInFrame = true;
|
||||
|
||||
mUploadMode = GetUploadMode();
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::CancelFrame() {
|
||||
MOZ_ASSERT(mInFrame);
|
||||
mCompositor->CancelFrame();
|
||||
mInFrame = false;
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::CompositorEndFrame() {
|
||||
nsTArray<FrameSurface> frameSurfaces = std::move(mFrameSurfaces);
|
||||
|
||||
if (!mInFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& frameSurface : frameSurfaces) {
|
||||
auto surfaceCursor = mSurfaces.find(frameSurface.mId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface& surface = surfaceCursor->second;
|
||||
|
||||
for (auto it = surface.mTiles.begin(); it != surface.mTiles.end(); ++it) {
|
||||
if (!it->second.mTexture) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gfx::Point tileOffset(it->first.mX * surface.mTileSize.width,
|
||||
it->first.mY * surface.mTileSize.height);
|
||||
gfx::Rect drawRect = it->second.mValidRect + tileOffset;
|
||||
|
||||
RefPtr<TexturedEffect> texturedEffect = CreateTexturedEffect(
|
||||
surface.mIsOpaque ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8,
|
||||
it->second.mTexture, frameSurface.mFilter, true);
|
||||
|
||||
texturedEffect->mTextureCoords =
|
||||
gfx::Rect(it->second.mValidRect.x / surface.mTileSize.width,
|
||||
it->second.mValidRect.y / surface.mTileSize.height,
|
||||
it->second.mValidRect.width / surface.mTileSize.width,
|
||||
it->second.mValidRect.height / surface.mTileSize.height);
|
||||
|
||||
EffectChain effect;
|
||||
effect.mPrimaryEffect = texturedEffect;
|
||||
mCompositor->DrawQuad(drawRect, frameSurface.mClipRect, effect, 1.0,
|
||||
frameSurface.mTransform, drawRect);
|
||||
void RenderCompositorD3D11SWGL::HandleExternalImage(
|
||||
RenderTextureHost* aExternalImage, FrameSurface& aFrameSurface) {
|
||||
// We need to hold the texture source separately from the effect,
|
||||
// since the effect doesn't hold a strong reference.
|
||||
RefPtr<DataTextureSourceD3D11> layer;
|
||||
RefPtr<TexturedEffect> texturedEffect;
|
||||
gfx::IntSize size;
|
||||
if (auto* host = aExternalImage->AsRenderDXGITextureHost()) {
|
||||
if (!host->EnsureD3D11Texture2D(GetDevice())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface.mExternalImage) {
|
||||
// We need to hold the texture source separately from the effect,
|
||||
// since the effect doesn't hold a strong reference.
|
||||
RefPtr<DataTextureSourceD3D11> layer;
|
||||
RefPtr<TexturedEffect> texturedEffect;
|
||||
gfx::IntSize size;
|
||||
if (auto* host = surface.mExternalImage->AsRenderDXGITextureHost()) {
|
||||
if (!host->EnsureD3D11Texture2D(mCompositor->GetDevice())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
layer = new DataTextureSourceD3D11(mCompositor->GetDevice(),
|
||||
host->GetFormat(),
|
||||
host->GetD3D11Texture2D());
|
||||
if (host->GetFormat() == SurfaceFormat::NV12 ||
|
||||
host->GetFormat() == SurfaceFormat::P010 ||
|
||||
host->GetFormat() == SurfaceFormat::P016) {
|
||||
texturedEffect = new EffectNV12(
|
||||
layer, host->GetYUVColorSpace(), host->GetColorRange(),
|
||||
host->GetColorDepth(), frameSurface.mFilter);
|
||||
} else {
|
||||
MOZ_ASSERT(host->GetFormat() == SurfaceFormat::B8G8R8X8 ||
|
||||
host->GetFormat() == SurfaceFormat::B8G8R8A8);
|
||||
texturedEffect = CreateTexturedEffect(host->GetFormat(), layer,
|
||||
frameSurface.mFilter, true);
|
||||
}
|
||||
size = host->GetSize(0);
|
||||
host->LockInternal();
|
||||
} else if (auto* host =
|
||||
surface.mExternalImage->AsRenderDXGIYCbCrTextureHost()) {
|
||||
if (!host->EnsureD3D11Texture2D(mCompositor->GetDevice())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
layer = new DataTextureSourceD3D11(mCompositor->GetDevice(),
|
||||
SurfaceFormat::A8,
|
||||
host->GetD3D11Texture2D(0));
|
||||
RefPtr<DataTextureSourceD3D11> u = new DataTextureSourceD3D11(
|
||||
mCompositor->GetDevice(), SurfaceFormat::A8,
|
||||
host->GetD3D11Texture2D(1));
|
||||
layer->SetNextSibling(u);
|
||||
RefPtr<DataTextureSourceD3D11> v = new DataTextureSourceD3D11(
|
||||
mCompositor->GetDevice(), SurfaceFormat::A8,
|
||||
host->GetD3D11Texture2D(2));
|
||||
u->SetNextSibling(v);
|
||||
|
||||
texturedEffect = new EffectYCbCr(
|
||||
layer, host->GetYUVColorSpace(), host->GetColorRange(),
|
||||
host->GetColorDepth(), frameSurface.mFilter);
|
||||
size = host->GetSize(0);
|
||||
host->LockInternal();
|
||||
}
|
||||
|
||||
gfx::Rect drawRect(0, 0, size.width, size.height);
|
||||
|
||||
EffectChain effect;
|
||||
effect.mPrimaryEffect = texturedEffect;
|
||||
mCompositor->DrawQuad(drawRect, frameSurface.mClipRect, effect, 1.0,
|
||||
frameSurface.mTransform, drawRect);
|
||||
|
||||
if (auto* host = surface.mExternalImage->AsRenderDXGITextureHost()) {
|
||||
host->Unlock();
|
||||
} else if (auto* host =
|
||||
surface.mExternalImage->AsRenderDXGIYCbCrTextureHost()) {
|
||||
host->Unlock();
|
||||
}
|
||||
layer = new DataTextureSourceD3D11(GetDevice(), host->GetFormat(),
|
||||
host->GetD3D11Texture2D());
|
||||
if (host->GetFormat() == SurfaceFormat::NV12 ||
|
||||
host->GetFormat() == SurfaceFormat::P010 ||
|
||||
host->GetFormat() == SurfaceFormat::P016) {
|
||||
texturedEffect =
|
||||
new EffectNV12(layer, host->GetYUVColorSpace(), host->GetColorRange(),
|
||||
host->GetColorDepth(), aFrameSurface.mFilter);
|
||||
} else {
|
||||
MOZ_ASSERT(host->GetFormat() == SurfaceFormat::B8G8R8X8 ||
|
||||
host->GetFormat() == SurfaceFormat::B8G8R8A8);
|
||||
texturedEffect = CreateTexturedEffect(host->GetFormat(), layer,
|
||||
aFrameSurface.mFilter, true);
|
||||
}
|
||||
size = host->GetSize(0);
|
||||
host->LockInternal();
|
||||
} else if (auto* host = aExternalImage->AsRenderDXGIYCbCrTextureHost()) {
|
||||
if (!host->EnsureD3D11Texture2D(GetDevice())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderedFrameId RenderCompositorD3D11SWGL::EndFrame(
|
||||
const nsTArray<DeviceIntRect>& aDirtyRects) {
|
||||
MOZ_ASSERT(mInFrame);
|
||||
mInFrame = false;
|
||||
mCompositor->EndFrame();
|
||||
return GetNextRenderFrameId();
|
||||
layer = new DataTextureSourceD3D11(GetDevice(), SurfaceFormat::A8,
|
||||
host->GetD3D11Texture2D(0));
|
||||
RefPtr<DataTextureSourceD3D11> u = new DataTextureSourceD3D11(
|
||||
GetDevice(), SurfaceFormat::A8, host->GetD3D11Texture2D(1));
|
||||
layer->SetNextSibling(u);
|
||||
RefPtr<DataTextureSourceD3D11> v = new DataTextureSourceD3D11(
|
||||
GetDevice(), SurfaceFormat::A8, host->GetD3D11Texture2D(2));
|
||||
u->SetNextSibling(v);
|
||||
|
||||
texturedEffect =
|
||||
new EffectYCbCr(layer, host->GetYUVColorSpace(), host->GetColorRange(),
|
||||
host->GetColorDepth(), aFrameSurface.mFilter);
|
||||
size = host->GetSize(0);
|
||||
host->LockInternal();
|
||||
}
|
||||
|
||||
gfx::Rect drawRect(0, 0, size.width, size.height);
|
||||
|
||||
EffectChain effect;
|
||||
effect.mPrimaryEffect = texturedEffect;
|
||||
mCompositor->DrawQuad(drawRect, aFrameSurface.mClipRect, effect, 1.0,
|
||||
aFrameSurface.mTransform, drawRect);
|
||||
|
||||
if (auto* host = aExternalImage->AsRenderDXGITextureHost()) {
|
||||
host->Unlock();
|
||||
} else if (auto* host = aExternalImage->AsRenderDXGIYCbCrTextureHost()) {
|
||||
host->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::Pause() {}
|
||||
|
||||
bool RenderCompositorD3D11SWGL::Resume() { return true; }
|
||||
|
||||
LayoutDeviceIntSize RenderCompositorD3D11SWGL::GetBufferSize() {
|
||||
return mWidget->GetClientSize();
|
||||
}
|
||||
|
||||
GLenum RenderCompositorD3D11SWGL::IsContextLost(bool aForce) {
|
||||
// CompositorD3D11 uses ID3D11Device for composite. The device status needs to
|
||||
// be checked.
|
||||
|
@ -243,84 +172,79 @@ GLenum RenderCompositorD3D11SWGL::IsContextLost(bool aForce) {
|
|||
}
|
||||
}
|
||||
|
||||
CompositorCapabilities RenderCompositorD3D11SWGL::GetCompositorCapabilities() {
|
||||
CompositorCapabilities caps;
|
||||
|
||||
caps.virtual_surface_size = 0;
|
||||
return caps;
|
||||
UniquePtr<RenderCompositorLayersSWGL::Surface>
|
||||
RenderCompositorD3D11SWGL::DoCreateSurface(wr::DeviceIntSize aTileSize,
|
||||
bool aIsOpaque) {
|
||||
return MakeUnique<SurfaceD3D11SWGL>(aTileSize, aIsOpaque);
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::Bind(wr::NativeTileId aId,
|
||||
wr::DeviceIntPoint* aOffset,
|
||||
uint32_t* aFboId,
|
||||
wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect) {
|
||||
MOZ_RELEASE_ASSERT(false);
|
||||
}
|
||||
SurfaceD3D11SWGL::SurfaceD3D11SWGL(wr::DeviceIntSize aTileSize, bool aIsOpaque)
|
||||
: Surface(aTileSize, aIsOpaque) {}
|
||||
|
||||
void RenderCompositorD3D11SWGL::Unbind() { MOZ_RELEASE_ASSERT(false); }
|
||||
RenderCompositorD3D11SWGL::TileD3D11::TileD3D11(
|
||||
layers::DataTextureSourceD3D11* aTexture, ID3D11Texture2D* aStagingTexture,
|
||||
DataSourceSurface* aDataSourceSurface, Surface* aOwner,
|
||||
RenderCompositorD3D11SWGL* aRenderCompositor)
|
||||
: Tile(),
|
||||
mTexture(aTexture),
|
||||
mStagingTexture(aStagingTexture),
|
||||
mSurface(aDataSourceSurface),
|
||||
mOwner(aOwner->AsSurfaceD3D11SWGL()),
|
||||
mRenderCompositor(aRenderCompositor) {}
|
||||
|
||||
bool RenderCompositorD3D11SWGL::MapTile(wr::NativeTileId aId,
|
||||
wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect,
|
||||
void** aData, int32_t* aStride) {
|
||||
auto surfaceCursor = mSurfaces.find(aId.surface_id);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface& surface = surfaceCursor->second;
|
||||
bool RenderCompositorD3D11SWGL::TileD3D11::Map(wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect,
|
||||
void** aData, int32_t* aStride) {
|
||||
const UploadMode uploadMode = mRenderCompositor->GetUploadMode();
|
||||
const gfx::IntSize tileSize = mOwner->TileSize();
|
||||
|
||||
auto layerCursor = surface.mTiles.find(TileKey(aId.x, aId.y));
|
||||
MOZ_RELEASE_ASSERT(layerCursor != surface.mTiles.end());
|
||||
|
||||
mCurrentTile = layerCursor->second;
|
||||
mCurrentTileId = aId;
|
||||
mCurrentTileDirty = IntRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
|
||||
aDirtyRect.size.width, aDirtyRect.size.height);
|
||||
|
||||
if (!mCurrentTile.mTexture) {
|
||||
if (!IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if this tile's upload method matches what we're using for this frame,
|
||||
// and if not then reallocate to fix it. Do this before we copy the struct
|
||||
// into mCurrentTile.
|
||||
if (mUploadMode == Upload_Immediate) {
|
||||
if (mCurrentTile.mStagingTexture) {
|
||||
MOZ_ASSERT(!mCurrentTile.mSurface);
|
||||
mCurrentTile.mStagingTexture = nullptr;
|
||||
mCurrentTile.mSurface = CreateStagingSurface(surface.TileSize());
|
||||
if (uploadMode == Upload_Immediate) {
|
||||
if (mStagingTexture) {
|
||||
MOZ_ASSERT(!mSurface);
|
||||
mStagingTexture = nullptr;
|
||||
mSurface = mRenderCompositor->CreateStagingSurface(tileSize);
|
||||
}
|
||||
} else {
|
||||
if (mCurrentTile.mSurface) {
|
||||
MOZ_ASSERT(!mCurrentTile.mStagingTexture);
|
||||
mCurrentTile.mSurface = nullptr;
|
||||
mCurrentTile.mStagingTexture = CreateStagingTexture(surface.TileSize());
|
||||
if (mSurface) {
|
||||
MOZ_ASSERT(!mStagingTexture);
|
||||
mSurface = nullptr;
|
||||
mStagingTexture = mRenderCompositor->CreateStagingTexture(tileSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (mUploadMode == Upload_Immediate) {
|
||||
mRenderCompositor->mCurrentStagingTexture = mStagingTexture;
|
||||
mRenderCompositor->mCurrentStagingTextureIsTemp = false;
|
||||
|
||||
if (uploadMode == Upload_Immediate) {
|
||||
DataSourceSurface::MappedSurface map;
|
||||
if (!mCurrentTile.mSurface->Map(DataSourceSurface::READ_WRITE, &map)) {
|
||||
if (!mSurface->Map(DataSourceSurface::READ_WRITE, &map)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*aData =
|
||||
map.mData + aValidRect.origin.y * map.mStride + aValidRect.origin.x * 4;
|
||||
*aStride = map.mStride;
|
||||
layerCursor->second.mValidRect =
|
||||
gfx::Rect(aValidRect.origin.x, aValidRect.origin.y,
|
||||
aValidRect.size.width, aValidRect.size.height);
|
||||
mValidRect = gfx::Rect(aValidRect.origin.x, aValidRect.origin.y,
|
||||
aValidRect.size.width, aValidRect.size.height);
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<ID3D11DeviceContext> context;
|
||||
mCompositor->GetDevice()->GetImmediateContext(getter_AddRefs(context));
|
||||
mRenderCompositor->GetDevice()->GetImmediateContext(getter_AddRefs(context));
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mappedSubresource;
|
||||
|
||||
bool shouldBlock = mUploadMode == Upload_Staging;
|
||||
bool shouldBlock = uploadMode == Upload_Staging;
|
||||
|
||||
HRESULT hr = context->Map(
|
||||
mCurrentTile.mStagingTexture, 0, D3D11_MAP_READ_WRITE,
|
||||
mRenderCompositor->mCurrentStagingTexture, 0, D3D11_MAP_READ_WRITE,
|
||||
shouldBlock ? 0 : D3D11_MAP_FLAG_DO_NOT_WAIT, &mappedSubresource);
|
||||
if (hr == DXGI_ERROR_WAS_STILL_DRAWING) {
|
||||
// mCurrentTile is a copy of the real tile data, so we can just replace the
|
||||
|
@ -330,27 +254,31 @@ bool RenderCompositorD3D11SWGL::MapTile(wr::NativeTileId aId,
|
|||
// having a pool of shared staging textures for all the tiles.
|
||||
|
||||
// Mark the tile as having a temporary staging texture.
|
||||
mCurrentTile.mIsTemp = true;
|
||||
mRenderCompositor->mCurrentStagingTextureIsTemp = true;
|
||||
|
||||
// Try grabbing a texture from the staging pool and see if we can use that.
|
||||
if (mUploadMode == Upload_StagingPooled && surface.mStagingPool.Length()) {
|
||||
mCurrentTile.mStagingTexture = surface.mStagingPool.ElementAt(0);
|
||||
surface.mStagingPool.RemoveElementAt(0);
|
||||
hr = context->Map(mCurrentTile.mStagingTexture, 0, D3D11_MAP_READ_WRITE,
|
||||
D3D11_MAP_FLAG_DO_NOT_WAIT, &mappedSubresource);
|
||||
if (uploadMode == Upload_StagingPooled && mOwner->mStagingPool.Length()) {
|
||||
mRenderCompositor->mCurrentStagingTexture =
|
||||
mOwner->mStagingPool.ElementAt(0);
|
||||
mOwner->mStagingPool.RemoveElementAt(0);
|
||||
hr = context->Map(mRenderCompositor->mCurrentStagingTexture, 0,
|
||||
D3D11_MAP_READ_WRITE, D3D11_MAP_FLAG_DO_NOT_WAIT,
|
||||
&mappedSubresource);
|
||||
|
||||
// If that failed, put it back into the pool (but at the end).
|
||||
if (hr == DXGI_ERROR_WAS_STILL_DRAWING) {
|
||||
surface.mStagingPool.AppendElement(mCurrentTile.mStagingTexture);
|
||||
mOwner->mStagingPool.AppendElement(
|
||||
mRenderCompositor->mCurrentStagingTexture);
|
||||
}
|
||||
}
|
||||
|
||||
// No staging textures, or we tried one and it was busy. Allocate a brand
|
||||
// new one instead.
|
||||
if (hr == DXGI_ERROR_WAS_STILL_DRAWING) {
|
||||
mCurrentTile.mStagingTexture = CreateStagingTexture(surface.TileSize());
|
||||
hr = context->Map(mCurrentTile.mStagingTexture, 0, D3D11_MAP_READ_WRITE,
|
||||
0, &mappedSubresource);
|
||||
mRenderCompositor->mCurrentStagingTexture =
|
||||
mRenderCompositor->CreateStagingTexture(tileSize);
|
||||
hr = context->Map(mRenderCompositor->mCurrentStagingTexture, 0,
|
||||
D3D11_MAP_READ_WRITE, 0, &mappedSubresource);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(SUCCEEDED(hr));
|
||||
|
@ -364,83 +292,66 @@ bool RenderCompositorD3D11SWGL::MapTile(wr::NativeTileId aId,
|
|||
*aStride = mappedSubresource.RowPitch;
|
||||
|
||||
// Store the new valid rect, so that we can composite only those pixels
|
||||
layerCursor->second.mValidRect =
|
||||
gfx::Rect(aValidRect.origin.x, aValidRect.origin.y, aValidRect.size.width,
|
||||
aValidRect.size.height);
|
||||
mValidRect = gfx::Rect(aValidRect.origin.x, aValidRect.origin.y,
|
||||
aValidRect.size.width, aValidRect.size.height);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::UnmapTile() {
|
||||
if (!mCurrentTile.mTexture) {
|
||||
void RenderCompositorD3D11SWGL::TileD3D11::Unmap(
|
||||
const gfx::IntRect& aDirtyRect) {
|
||||
const UploadMode uploadMode = mRenderCompositor->GetUploadMode();
|
||||
|
||||
if (!IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCurrentTile.mSurface) {
|
||||
MOZ_ASSERT(mUploadMode == Upload_Immediate);
|
||||
mCurrentTile.mSurface->Unmap();
|
||||
nsIntRegion dirty(mCurrentTileDirty);
|
||||
if (mSurface) {
|
||||
MOZ_ASSERT(uploadMode == Upload_Immediate);
|
||||
mSurface->Unmap();
|
||||
nsIntRegion dirty(aDirtyRect);
|
||||
// This uses UpdateSubresource, which blocks, so is likely implemented as a
|
||||
// memcpy into driver owned memory, followed by an async upload. The staging
|
||||
// method should avoid this extra copy, and is likely to be faster usually.
|
||||
// We could possible do this call on a background thread so that sw-wr can
|
||||
// start drawing the next tile while the memcpy is in progress.
|
||||
mCurrentTile.mTexture->Update(mCurrentTile.mSurface, &dirty);
|
||||
mTexture->Update(mSurface, &dirty);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ID3D11DeviceContext> context;
|
||||
mCompositor->GetDevice()->GetImmediateContext(getter_AddRefs(context));
|
||||
mRenderCompositor->GetDevice()->GetImmediateContext(getter_AddRefs(context));
|
||||
|
||||
context->Unmap(mCurrentTile.mStagingTexture, 0);
|
||||
context->Unmap(mRenderCompositor->mCurrentStagingTexture, 0);
|
||||
|
||||
D3D11_BOX box;
|
||||
box.front = 0;
|
||||
box.back = 1;
|
||||
box.left = mCurrentTileDirty.X();
|
||||
box.top = mCurrentTileDirty.Y();
|
||||
box.right = mCurrentTileDirty.XMost();
|
||||
box.bottom = mCurrentTileDirty.YMost();
|
||||
box.left = aDirtyRect.X();
|
||||
box.top = aDirtyRect.Y();
|
||||
box.right = aDirtyRect.XMost();
|
||||
box.bottom = aDirtyRect.YMost();
|
||||
|
||||
context->CopySubresourceRegion(mCurrentTile.mTexture->GetD3D11Texture(), 0,
|
||||
mCurrentTileDirty.x, mCurrentTileDirty.y, 0,
|
||||
mCurrentTile.mStagingTexture, 0, &box);
|
||||
context->CopySubresourceRegion(
|
||||
mTexture->GetD3D11Texture(), 0, aDirtyRect.x, aDirtyRect.y, 0,
|
||||
mRenderCompositor->mCurrentStagingTexture, 0, &box);
|
||||
|
||||
// If we allocated a temp staging texture for this tile, and we're running
|
||||
// in pooled mode, then consider adding it to the pool for later.
|
||||
if (mCurrentTile.mIsTemp && mUploadMode == Upload_StagingPooled) {
|
||||
auto surfaceCursor = mSurfaces.find(mCurrentTileId.surface_id);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface& surface = surfaceCursor->second;
|
||||
|
||||
if (mRenderCompositor->mCurrentStagingTextureIsTemp &&
|
||||
uploadMode == Upload_StagingPooled) {
|
||||
static const uint32_t kMaxPoolSize = 5;
|
||||
if (surface.mStagingPool.Length() < kMaxPoolSize) {
|
||||
surface.mStagingPool.AppendElement(mCurrentTile.mStagingTexture);
|
||||
if (mOwner->mStagingPool.Length() < kMaxPoolSize) {
|
||||
mOwner->mStagingPool.AppendElement(
|
||||
mRenderCompositor->mCurrentStagingTexture);
|
||||
}
|
||||
}
|
||||
mCurrentTile.mStagingTexture = nullptr;
|
||||
|
||||
mRenderCompositor->mCurrentStagingTexture = nullptr;
|
||||
mRenderCompositor->mCurrentStagingTextureIsTemp = false;
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::CreateSurface(wr::NativeSurfaceId aId,
|
||||
wr::DeviceIntPoint aVirtualOffset,
|
||||
wr::DeviceIntSize aTileSize,
|
||||
bool aIsOpaque) {
|
||||
MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
|
||||
mSurfaces.insert({aId, Surface{aTileSize, aIsOpaque}});
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::CreateExternalSurface(wr::NativeSurfaceId aId,
|
||||
bool aIsOpaque) {
|
||||
MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
|
||||
Surface surface{wr::DeviceIntSize{}, aIsOpaque};
|
||||
surface.mIsExternal = true;
|
||||
mSurfaces.insert({aId, std::move(surface)});
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::DestroySurface(NativeSurfaceId aId) {
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
mSurfaces.erase(surfaceCursor);
|
||||
}
|
||||
bool RenderCompositorD3D11SWGL::TileD3D11::IsValid() { return !!mTexture; }
|
||||
|
||||
already_AddRefed<ID3D11Texture2D>
|
||||
RenderCompositorD3D11SWGL::CreateStagingTexture(const gfx::IntSize aSize) {
|
||||
|
@ -452,8 +363,8 @@ RenderCompositorD3D11SWGL::CreateStagingTexture(const gfx::IntSize aSize) {
|
|||
desc.BindFlags = 0;
|
||||
|
||||
RefPtr<ID3D11Texture2D> cpuTexture;
|
||||
DebugOnly<HRESULT> hr = mCompositor->GetDevice()->CreateTexture2D(
|
||||
&desc, nullptr, getter_AddRefs(cpuTexture));
|
||||
DebugOnly<HRESULT> hr =
|
||||
GetDevice()->CreateTexture2D(&desc, nullptr, getter_AddRefs(cpuTexture));
|
||||
MOZ_ASSERT(SUCCEEDED(hr));
|
||||
return cpuTexture.forget();
|
||||
}
|
||||
|
@ -463,103 +374,41 @@ RenderCompositorD3D11SWGL::CreateStagingSurface(const gfx::IntSize aSize) {
|
|||
return Factory::CreateDataSourceSurface(aSize, SurfaceFormat::B8G8R8A8);
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::CreateTile(wr::NativeSurfaceId aId, int32_t aX,
|
||||
int32_t aY) {
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface& surface = surfaceCursor->second;
|
||||
MOZ_RELEASE_ASSERT(!surface.mIsExternal);
|
||||
UniquePtr<RenderCompositorLayersSWGL::Tile>
|
||||
RenderCompositorD3D11SWGL::DoCreateTile(Surface* aSurface) {
|
||||
MOZ_RELEASE_ASSERT(aSurface);
|
||||
|
||||
const auto tileSize = aSurface->TileSize();
|
||||
|
||||
if (mUploadMode == Upload_Immediate) {
|
||||
RefPtr<DataTextureSourceD3D11> source =
|
||||
new DataTextureSourceD3D11(gfx::SurfaceFormat::B8G8R8A8, mCompositor,
|
||||
layers::TextureFlags::NO_FLAGS);
|
||||
RefPtr<DataSourceSurface> surf = CreateStagingSurface(surface.TileSize());
|
||||
surface.mTiles.insert({TileKey(aX, aY), Tile{source, nullptr, surf}});
|
||||
return;
|
||||
RefPtr<DataSourceSurface> surf = CreateStagingSurface(tileSize);
|
||||
return MakeUnique<TileD3D11>(source, nullptr, surf, aSurface, this);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mUploadMode == Upload_Staging ||
|
||||
mUploadMode == Upload_StagingNoBlock ||
|
||||
mUploadMode == Upload_StagingPooled);
|
||||
|
||||
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
surface.mTileSize.width, surface.mTileSize.height,
|
||||
1, 1);
|
||||
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, tileSize.width,
|
||||
tileSize.height, 1, 1);
|
||||
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
DebugOnly<HRESULT> hr = mCompositor->GetDevice()->CreateTexture2D(
|
||||
&desc, nullptr, getter_AddRefs(texture));
|
||||
DebugOnly<HRESULT> hr =
|
||||
GetDevice()->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
|
||||
MOZ_ASSERT(SUCCEEDED(hr));
|
||||
if (!texture) {
|
||||
gfxCriticalNote << "Failed to allocate Texture2D: " << surface.TileSize();
|
||||
surface.mTiles.insert({TileKey(aX, aY), Tile{nullptr, nullptr, nullptr}});
|
||||
return;
|
||||
gfxCriticalNote << "Failed to allocate Texture2D: " << aSurface->TileSize();
|
||||
MakeUnique<TileD3D11>(nullptr, nullptr, nullptr, aSurface, this);
|
||||
}
|
||||
|
||||
RefPtr<DataTextureSourceD3D11> source = new DataTextureSourceD3D11(
|
||||
mCompositor->GetDevice(), gfx::SurfaceFormat::B8G8R8A8, texture);
|
||||
GetDevice(), gfx::SurfaceFormat::B8G8R8A8, texture);
|
||||
|
||||
RefPtr<ID3D11Texture2D> cpuTexture = CreateStagingTexture(surface.TileSize());
|
||||
surface.mTiles.insert({TileKey(aX, aY), Tile{source, cpuTexture, nullptr}});
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::DestroyTile(wr::NativeSurfaceId aId, int32_t aX,
|
||||
int32_t aY) {
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface& surface = surfaceCursor->second;
|
||||
MOZ_RELEASE_ASSERT(!surface.mIsExternal);
|
||||
|
||||
auto layerCursor = surface.mTiles.find(TileKey(aX, aY));
|
||||
MOZ_RELEASE_ASSERT(layerCursor != surface.mTiles.end());
|
||||
surface.mTiles.erase(layerCursor);
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::AttachExternalImage(
|
||||
wr::NativeSurfaceId aId, wr::ExternalImageId aExternalImage) {
|
||||
RenderTextureHost* image =
|
||||
RenderThread::Get()->GetRenderTexture(aExternalImage);
|
||||
MOZ_ASSERT(image);
|
||||
if (!image) {
|
||||
gfxCriticalNoteOnce
|
||||
<< "Failed to get RenderTextureHost for D3D11SWGL extId:"
|
||||
<< AsUint64(aExternalImage);
|
||||
return;
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(image->AsRenderDXGITextureHost() ||
|
||||
image->AsRenderDXGIYCbCrTextureHost());
|
||||
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
|
||||
Surface& surface = surfaceCursor->second;
|
||||
surface.mExternalImage = image;
|
||||
MOZ_RELEASE_ASSERT(surface.mTiles.empty());
|
||||
MOZ_RELEASE_ASSERT(surface.mIsExternal);
|
||||
}
|
||||
|
||||
gfx::SamplingFilter ToSamplingFilter(wr::ImageRendering aImageRendering) {
|
||||
if (aImageRendering == wr::ImageRendering::Auto) {
|
||||
return gfx::SamplingFilter::LINEAR;
|
||||
}
|
||||
return gfx::SamplingFilter::POINT;
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::AddSurface(
|
||||
wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform,
|
||||
wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering) {
|
||||
Matrix4x4 transform(
|
||||
aTransform.m11, aTransform.m12, aTransform.m13, aTransform.m14,
|
||||
aTransform.m21, aTransform.m22, aTransform.m23, aTransform.m24,
|
||||
aTransform.m31, aTransform.m32, aTransform.m33, aTransform.m34,
|
||||
aTransform.m41, aTransform.m42, aTransform.m43, aTransform.m44);
|
||||
|
||||
gfx::IntRect clipRect(aClipRect.origin.x, aClipRect.origin.y,
|
||||
aClipRect.size.width, aClipRect.size.height);
|
||||
|
||||
mFrameSurfaces.AppendElement(FrameSurface{aId, transform, clipRect,
|
||||
ToSamplingFilter(aImageRendering)});
|
||||
RefPtr<ID3D11Texture2D> cpuTexture = CreateStagingTexture(tileSize);
|
||||
return MakeUnique<TileD3D11>(source, cpuTexture, nullptr, aSurface, this);
|
||||
}
|
||||
|
||||
bool RenderCompositorD3D11SWGL::MaybeReadback(
|
||||
|
@ -576,44 +425,7 @@ bool RenderCompositorD3D11SWGL::MaybeReadback(
|
|||
return false;
|
||||
}
|
||||
|
||||
mCompositor->Readback(dt);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderCompositorD3D11SWGL::MaybeRequestAllowFrameRecording(
|
||||
bool aWillRecord) {
|
||||
mCompositor->RequestAllowFrameRecording(aWillRecord);
|
||||
}
|
||||
|
||||
bool RenderCompositorD3D11SWGL::MaybeRecordFrame(
|
||||
layers::CompositionRecorder& aRecorder) {
|
||||
layers::WindowLMC window(mCompositor);
|
||||
gfx::IntSize size = GetBufferSize().ToUnknownSize();
|
||||
RefPtr<layers::profiler_screenshots::RenderSource> snapshot =
|
||||
window.GetWindowContents(size);
|
||||
if (!snapshot) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<layers::profiler_screenshots::AsyncReadbackBuffer> buffer =
|
||||
window.CreateAsyncReadbackBuffer(size);
|
||||
buffer->CopyFrom(snapshot);
|
||||
|
||||
RefPtr<layers::RecordedFrame> frame =
|
||||
new RenderCompositorRecordedFrame(TimeStamp::Now(), std::move(buffer));
|
||||
aRecorder.RecordFrame(frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RenderCompositorD3D11SWGL::MaybeGrabScreenshot(
|
||||
const gfx::IntSize& aWindowSize) {
|
||||
layers::WindowLMC window(mCompositor);
|
||||
mProfilerScreenshotGrabber.MaybeGrabScreenshot(window, aWindowSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderCompositorD3D11SWGL::MaybeProcessScreenshotQueue() {
|
||||
mProfilerScreenshotGrabber.MaybeProcessQueue();
|
||||
GetCompositorD3D11()->Readback(dt);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,13 +10,15 @@
|
|||
#include "mozilla/layers/ScreenshotGrabber.h"
|
||||
#include "mozilla/layers/TextureD3D11.h"
|
||||
#include "mozilla/layers/CompositorD3D11.h"
|
||||
#include "mozilla/webrender/RenderCompositor.h"
|
||||
#include "mozilla/webrender/RenderCompositorLayersSWGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace wr {
|
||||
|
||||
class RenderCompositorD3D11SWGL : public RenderCompositor {
|
||||
class SurfaceD3D11SWGL;
|
||||
|
||||
class RenderCompositorD3D11SWGL : public RenderCompositorLayersSWGL {
|
||||
public:
|
||||
static UniquePtr<RenderCompositor> Create(
|
||||
RefPtr<widget::CompositorWidget>&& aWidget, nsACString& aError);
|
||||
|
@ -26,29 +28,11 @@ class RenderCompositorD3D11SWGL : public RenderCompositor {
|
|||
void* aContext);
|
||||
virtual ~RenderCompositorD3D11SWGL();
|
||||
|
||||
void* swgl() const override { return mContext; }
|
||||
|
||||
bool MakeCurrent() override;
|
||||
|
||||
bool BeginFrame() override;
|
||||
void CancelFrame() override;
|
||||
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
|
||||
|
||||
void Pause() override;
|
||||
bool Resume() override;
|
||||
|
||||
bool SurfaceOriginIsTopLeft() override { return true; }
|
||||
|
||||
LayoutDeviceIntSize GetBufferSize() override;
|
||||
|
||||
GLenum IsContextLost(bool aForce) override;
|
||||
|
||||
// Should we support this?
|
||||
bool SupportsExternalBufferTextures() const override { return false; }
|
||||
|
||||
layers::WebRenderBackend BackendType() const override {
|
||||
return layers::WebRenderBackend::SOFTWARE;
|
||||
}
|
||||
layers::WebRenderCompositor CompositorType() const override {
|
||||
return layers::WebRenderCompositor::D3D11;
|
||||
}
|
||||
|
@ -56,55 +40,18 @@ class RenderCompositorD3D11SWGL : public RenderCompositor {
|
|||
return this;
|
||||
}
|
||||
|
||||
// Interface for wr::Compositor
|
||||
CompositorCapabilities GetCompositorCapabilities() override;
|
||||
|
||||
bool ShouldUseNativeCompositor() override { return true; }
|
||||
|
||||
void CompositorBeginFrame() override {}
|
||||
void CompositorEndFrame() override;
|
||||
void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
|
||||
wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect) override;
|
||||
void Unbind() override;
|
||||
bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect, void** aData,
|
||||
int32_t* aStride) override;
|
||||
void UnmapTile() override;
|
||||
void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
|
||||
wr::DeviceIntSize aTileSize, bool aIsOpaque) override;
|
||||
void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque) override;
|
||||
void DestroySurface(NativeSurfaceId aId) override;
|
||||
void CreateTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) override;
|
||||
void DestroyTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) override;
|
||||
void AttachExternalImage(wr::NativeSurfaceId aId,
|
||||
wr::ExternalImageId aExternalImage) override;
|
||||
void AddSurface(wr::NativeSurfaceId aId,
|
||||
const wr::CompositorSurfaceTransform& aTransform,
|
||||
wr::DeviceIntRect aClipRect,
|
||||
wr::ImageRendering aImageRendering) override;
|
||||
void EnableNativeCompositor(bool aEnable) override {}
|
||||
void DeInit() override {}
|
||||
bool BeginFrame() override;
|
||||
|
||||
bool MaybeReadback(const gfx::IntSize& aReadbackSize,
|
||||
const wr::ImageFormat& aReadbackFormat,
|
||||
const Range<uint8_t>& aReadbackBuffer,
|
||||
bool* aNeedsYFlip) override;
|
||||
void MaybeRequestAllowFrameRecording(bool aWillRecord) override;
|
||||
bool MaybeRecordFrame(layers::CompositionRecorder& aRecorder) override;
|
||||
bool MaybeGrabScreenshot(const gfx::IntSize& aWindowSize) override;
|
||||
bool MaybeProcessScreenshotQueue() override;
|
||||
|
||||
// TODO: Screenshots etc
|
||||
layers::CompositorD3D11* GetCompositorD3D11() {
|
||||
return mCompositor->AsCompositorD3D11();
|
||||
}
|
||||
|
||||
struct TileKey {
|
||||
TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {}
|
||||
|
||||
int32_t mX;
|
||||
int32_t mY;
|
||||
};
|
||||
|
||||
ID3D11Device* GetDevice() { return mCompositor->GetDevice(); }
|
||||
ID3D11Device* GetDevice() { return GetCompositorD3D11()->GetDevice(); }
|
||||
|
||||
private:
|
||||
already_AddRefed<ID3D11Texture2D> CreateStagingTexture(
|
||||
|
@ -112,52 +59,35 @@ class RenderCompositorD3D11SWGL : public RenderCompositor {
|
|||
already_AddRefed<DataSourceSurface> CreateStagingSurface(
|
||||
const gfx::IntSize aSize);
|
||||
|
||||
RefPtr<layers::CompositorD3D11> mCompositor;
|
||||
void* mContext = nullptr;
|
||||
void HandleExternalImage(RenderTextureHost* aExternalImage,
|
||||
FrameSurface& aFrameSurface) override;
|
||||
UniquePtr<RenderCompositorLayersSWGL::Surface> DoCreateSurface(
|
||||
wr::DeviceIntSize aTileSize, bool aIsOpaque) override;
|
||||
UniquePtr<RenderCompositorLayersSWGL::Tile> DoCreateTile(
|
||||
Surface* aSurface) override;
|
||||
|
||||
struct Tile {
|
||||
// Each tile retains a texture, and a DataSourceSurface of the
|
||||
// same size. We draw into the source surface, and then copy the
|
||||
// changed area into the texture.
|
||||
class TileD3D11 : public RenderCompositorLayersSWGL::Tile {
|
||||
public:
|
||||
TileD3D11(layers::DataTextureSourceD3D11* aTexture,
|
||||
ID3D11Texture2D* aStagingTexture,
|
||||
DataSourceSurface* aDataSourceSurface, Surface* aOwner,
|
||||
RenderCompositorD3D11SWGL* aRenderCompositor);
|
||||
virtual ~TileD3D11() {}
|
||||
|
||||
bool Map(wr::DeviceIntRect aDirtyRect, wr::DeviceIntRect aValidRect,
|
||||
void** aData, int32_t* aStride) override;
|
||||
void Unmap(const gfx::IntRect& aDirtyRect) override;
|
||||
layers::DataTextureSource* GetTextureSource() override { return mTexture; }
|
||||
bool IsValid() override;
|
||||
|
||||
private:
|
||||
RefPtr<layers::DataTextureSourceD3D11> mTexture;
|
||||
RefPtr<ID3D11Texture2D> mStagingTexture;
|
||||
RefPtr<DataSourceSurface> mSurface;
|
||||
gfx::Rect mValidRect;
|
||||
bool mIsTemp = false;
|
||||
|
||||
struct KeyHashFn {
|
||||
std::size_t operator()(const TileKey& aId) const {
|
||||
return HashGeneric(aId.mX, aId.mY);
|
||||
}
|
||||
};
|
||||
SurfaceD3D11SWGL* mOwner;
|
||||
RenderCompositorD3D11SWGL* mRenderCompositor;
|
||||
};
|
||||
|
||||
struct Surface {
|
||||
explicit Surface(wr::DeviceIntSize aTileSize, bool aIsOpaque)
|
||||
: mTileSize(aTileSize), mIsOpaque(aIsOpaque) {}
|
||||
gfx::IntSize TileSize() {
|
||||
return gfx::IntSize(mTileSize.width, mTileSize.height);
|
||||
}
|
||||
|
||||
// External images can change size depending on which image
|
||||
// is attached, so mTileSize will be 0,0 when mIsExternal
|
||||
// is true.
|
||||
wr::DeviceIntSize mTileSize;
|
||||
bool mIsOpaque;
|
||||
bool mIsExternal = false;
|
||||
std::unordered_map<TileKey, Tile, Tile::KeyHashFn> mTiles;
|
||||
RefPtr<RenderTextureHost> mExternalImage;
|
||||
|
||||
nsTArray<RefPtr<ID3D11Texture2D>> mStagingPool;
|
||||
|
||||
struct IdHashFn {
|
||||
std::size_t operator()(const wr::NativeSurfaceId& aId) const {
|
||||
return HashGeneric(wr::AsUint64(aId));
|
||||
}
|
||||
};
|
||||
};
|
||||
std::unordered_map<wr::NativeSurfaceId, Surface, Surface::IdHashFn> mSurfaces;
|
||||
|
||||
enum UploadMode {
|
||||
Upload_Immediate,
|
||||
Upload_Staging,
|
||||
|
@ -167,28 +97,19 @@ class RenderCompositorD3D11SWGL : public RenderCompositor {
|
|||
UploadMode GetUploadMode();
|
||||
UploadMode mUploadMode = Upload_Staging;
|
||||
|
||||
// Temporary state held between MapTile and UnmapTile
|
||||
Tile mCurrentTile;
|
||||
gfx::IntRect mCurrentTileDirty;
|
||||
wr::NativeTileId mCurrentTileId;
|
||||
|
||||
// The set of surfaces added to be composited for the current frame
|
||||
struct FrameSurface {
|
||||
wr::NativeSurfaceId mId;
|
||||
gfx::Matrix4x4 mTransform;
|
||||
gfx::IntRect mClipRect;
|
||||
gfx::SamplingFilter mFilter;
|
||||
};
|
||||
nsTArray<FrameSurface> mFrameSurfaces;
|
||||
bool mInFrame = false;
|
||||
|
||||
layers::ScreenshotGrabber mProfilerScreenshotGrabber;
|
||||
RefPtr<ID3D11Texture2D> mCurrentStagingTexture;
|
||||
bool mCurrentStagingTextureIsTemp = false;
|
||||
};
|
||||
|
||||
static inline bool operator==(const RenderCompositorD3D11SWGL::TileKey& a0,
|
||||
const RenderCompositorD3D11SWGL::TileKey& a1) {
|
||||
return a0.mX == a1.mX && a0.mY == a1.mY;
|
||||
}
|
||||
class SurfaceD3D11SWGL : public RenderCompositorLayersSWGL::Surface {
|
||||
public:
|
||||
SurfaceD3D11SWGL(wr::DeviceIntSize aTileSize, bool aIsOpaque);
|
||||
virtual ~SurfaceD3D11SWGL() {}
|
||||
|
||||
SurfaceD3D11SWGL* AsSurfaceD3D11SWGL() override { return this; }
|
||||
|
||||
nsTArray<RefPtr<ID3D11Texture2D>> mStagingPool;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -0,0 +1,321 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "RenderCompositorLayersSWGL.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "mozilla/layers/BuildConstants.h"
|
||||
#include "mozilla/layers/Effects.h"
|
||||
#include "mozilla/layers/TextureHostOGL.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "RenderCompositorRecordedFrame.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include "mozilla/webrender/RenderCompositorD3D11SWGL.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
using namespace layers;
|
||||
|
||||
namespace wr {
|
||||
|
||||
UniquePtr<RenderCompositor> RenderCompositorLayersSWGL::Create(
|
||||
RefPtr<widget::CompositorWidget>&& aWidget, nsACString& aError) {
|
||||
#ifdef XP_WIN
|
||||
return RenderCompositorD3D11SWGL::Create(std::move(aWidget), aError);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
RenderCompositorLayersSWGL::RenderCompositorLayersSWGL(
|
||||
Compositor* aCompositor, RefPtr<widget::CompositorWidget>&& aWidget,
|
||||
void* aContext)
|
||||
: RenderCompositor(std::move(aWidget)),
|
||||
mCompositor(aCompositor),
|
||||
mContext(aContext) {
|
||||
MOZ_ASSERT(mCompositor);
|
||||
MOZ_ASSERT(mContext);
|
||||
}
|
||||
|
||||
RenderCompositorLayersSWGL::~RenderCompositorLayersSWGL() {
|
||||
wr_swgl_destroy_context(mContext);
|
||||
}
|
||||
|
||||
bool RenderCompositorLayersSWGL::MakeCurrent() {
|
||||
wr_swgl_make_current(mContext);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderCompositorLayersSWGL::BeginFrame() {
|
||||
MOZ_ASSERT(!mInFrame);
|
||||
MakeCurrent();
|
||||
gfx::IntRect rect =
|
||||
gfx::IntRect(gfx::IntPoint(0, 0), GetBufferSize().ToUnknownSize());
|
||||
if (!mCompositor->BeginFrameForWindow(nsIntRegion(rect), Nothing(), rect,
|
||||
nsIntRegion())) {
|
||||
return false;
|
||||
}
|
||||
mInFrame = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::CancelFrame() {
|
||||
MOZ_ASSERT(mInFrame);
|
||||
mCompositor->CancelFrame();
|
||||
mInFrame = false;
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::CompositorEndFrame() {
|
||||
nsTArray<FrameSurface> frameSurfaces = std::move(mFrameSurfaces);
|
||||
|
||||
if (!mInFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& frameSurface : frameSurfaces) {
|
||||
auto surfaceCursor = mSurfaces.find(frameSurface.mId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface* surface = surfaceCursor->second.get();
|
||||
|
||||
for (auto it = surface->mTiles.begin(); it != surface->mTiles.end(); ++it) {
|
||||
if (!it->second->IsValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gfx::Point tileOffset(it->first.mX * surface->mTileSize.width,
|
||||
it->first.mY * surface->mTileSize.height);
|
||||
gfx::Rect drawRect = it->second->mValidRect + tileOffset;
|
||||
|
||||
RefPtr<TexturedEffect> texturedEffect = CreateTexturedEffect(
|
||||
surface->mIsOpaque ? gfx::SurfaceFormat::B8G8R8X8
|
||||
: gfx::SurfaceFormat::B8G8R8A8,
|
||||
it->second->GetTextureSource(), frameSurface.mFilter, true);
|
||||
|
||||
texturedEffect->mTextureCoords =
|
||||
gfx::Rect(it->second->mValidRect.x / surface->mTileSize.width,
|
||||
it->second->mValidRect.y / surface->mTileSize.height,
|
||||
it->second->mValidRect.width / surface->mTileSize.width,
|
||||
it->second->mValidRect.height / surface->mTileSize.height);
|
||||
|
||||
EffectChain effect;
|
||||
effect.mPrimaryEffect = texturedEffect;
|
||||
mCompositor->DrawQuad(drawRect, frameSurface.mClipRect, effect, 1.0,
|
||||
frameSurface.mTransform, drawRect);
|
||||
}
|
||||
|
||||
if (surface->mExternalImage) {
|
||||
HandleExternalImage(surface->mExternalImage, frameSurface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderedFrameId RenderCompositorLayersSWGL::EndFrame(
|
||||
const nsTArray<DeviceIntRect>& aDirtyRects) {
|
||||
MOZ_ASSERT(mInFrame);
|
||||
mInFrame = false;
|
||||
mCompositor->EndFrame();
|
||||
return GetNextRenderFrameId();
|
||||
}
|
||||
|
||||
LayoutDeviceIntSize RenderCompositorLayersSWGL::GetBufferSize() {
|
||||
return mWidget->GetClientSize();
|
||||
}
|
||||
|
||||
CompositorCapabilities RenderCompositorLayersSWGL::GetCompositorCapabilities() {
|
||||
CompositorCapabilities caps;
|
||||
|
||||
caps.virtual_surface_size = 0;
|
||||
return caps;
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::Bind(wr::NativeTileId aId,
|
||||
wr::DeviceIntPoint* aOffset,
|
||||
uint32_t* aFboId,
|
||||
wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect) {
|
||||
MOZ_RELEASE_ASSERT(false);
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::Unbind() { MOZ_RELEASE_ASSERT(false); }
|
||||
|
||||
bool RenderCompositorLayersSWGL::MapTile(wr::NativeTileId aId,
|
||||
wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect,
|
||||
void** aData, int32_t* aStride) {
|
||||
auto surfaceCursor = mSurfaces.find(aId.surface_id);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface* surface = surfaceCursor->second.get();
|
||||
|
||||
auto layerCursor = surface->mTiles.find(TileKey(aId.x, aId.y));
|
||||
MOZ_RELEASE_ASSERT(layerCursor != surface->mTiles.end());
|
||||
|
||||
mCurrentTile = layerCursor->second.get();
|
||||
mCurrentTileId = aId;
|
||||
mCurrentTileDirty =
|
||||
gfx::IntRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
|
||||
aDirtyRect.size.width, aDirtyRect.size.height);
|
||||
|
||||
if (!mCurrentTile->Map(aDirtyRect, aValidRect, aData, aStride)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store the new valid rect, so that we can composite only those pixels
|
||||
mCurrentTile->mValidRect =
|
||||
gfx::Rect(aValidRect.origin.x, aValidRect.origin.y, aValidRect.size.width,
|
||||
aValidRect.size.height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::UnmapTile() {
|
||||
mCurrentTile->Unmap(mCurrentTileDirty);
|
||||
mCurrentTile = nullptr;
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::CreateSurface(
|
||||
wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
|
||||
wr::DeviceIntSize aTileSize, bool aIsOpaque) {
|
||||
MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
|
||||
auto surface = DoCreateSurface(aTileSize, aIsOpaque);
|
||||
mSurfaces.insert({aId, std::move(surface)});
|
||||
}
|
||||
|
||||
UniquePtr<RenderCompositorLayersSWGL::Surface>
|
||||
RenderCompositorLayersSWGL::DoCreateSurface(wr::DeviceIntSize aTileSize,
|
||||
bool aIsOpaque) {
|
||||
return MakeUnique<Surface>(aTileSize, aIsOpaque);
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::CreateExternalSurface(wr::NativeSurfaceId aId,
|
||||
bool aIsOpaque) {
|
||||
MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
|
||||
auto surface = MakeUnique<Surface>(wr::DeviceIntSize{}, aIsOpaque);
|
||||
surface->mIsExternal = true;
|
||||
mSurfaces.insert({aId, std::move(surface)});
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::DestroySurface(NativeSurfaceId aId) {
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
mSurfaces.erase(surfaceCursor);
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::CreateTile(wr::NativeSurfaceId aId, int32_t aX,
|
||||
int32_t aY) {
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface* surface = surfaceCursor->second.get();
|
||||
MOZ_RELEASE_ASSERT(!surface->mIsExternal);
|
||||
|
||||
auto tile = DoCreateTile(surface);
|
||||
surface->mTiles.insert({TileKey(aX, aY), std::move(tile)});
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::DestroyTile(wr::NativeSurfaceId aId,
|
||||
int32_t aX, int32_t aY) {
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
Surface* surface = surfaceCursor->second.get();
|
||||
MOZ_RELEASE_ASSERT(!surface->mIsExternal);
|
||||
|
||||
auto layerCursor = surface->mTiles.find(TileKey(aX, aY));
|
||||
MOZ_RELEASE_ASSERT(layerCursor != surface->mTiles.end());
|
||||
surface->mTiles.erase(layerCursor);
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::AttachExternalImage(
|
||||
wr::NativeSurfaceId aId, wr::ExternalImageId aExternalImage) {
|
||||
RenderTextureHost* image =
|
||||
RenderThread::Get()->GetRenderTexture(aExternalImage);
|
||||
MOZ_ASSERT(image);
|
||||
if (!image) {
|
||||
gfxCriticalNoteOnce
|
||||
<< "Failed to get RenderTextureHost for D3D11SWGL extId:"
|
||||
<< AsUint64(aExternalImage);
|
||||
return;
|
||||
}
|
||||
#if defined(XP_WIN)
|
||||
MOZ_RELEASE_ASSERT(image->AsRenderDXGITextureHost() ||
|
||||
image->AsRenderDXGIYCbCrTextureHost());
|
||||
#endif
|
||||
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
|
||||
|
||||
Surface* surface = surfaceCursor->second.get();
|
||||
surface->mExternalImage = image;
|
||||
MOZ_RELEASE_ASSERT(surface->mTiles.empty());
|
||||
MOZ_RELEASE_ASSERT(surface->mIsExternal);
|
||||
}
|
||||
|
||||
// static
|
||||
gfx::SamplingFilter RenderCompositorLayersSWGL::ToSamplingFilter(
|
||||
wr::ImageRendering aImageRendering) {
|
||||
if (aImageRendering == wr::ImageRendering::Auto) {
|
||||
return gfx::SamplingFilter::LINEAR;
|
||||
}
|
||||
return gfx::SamplingFilter::POINT;
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::AddSurface(
|
||||
wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform,
|
||||
wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering) {
|
||||
gfx::Matrix4x4 transform(
|
||||
aTransform.m11, aTransform.m12, aTransform.m13, aTransform.m14,
|
||||
aTransform.m21, aTransform.m22, aTransform.m23, aTransform.m24,
|
||||
aTransform.m31, aTransform.m32, aTransform.m33, aTransform.m34,
|
||||
aTransform.m41, aTransform.m42, aTransform.m43, aTransform.m44);
|
||||
|
||||
gfx::IntRect clipRect(aClipRect.origin.x, aClipRect.origin.y,
|
||||
aClipRect.size.width, aClipRect.size.height);
|
||||
|
||||
mFrameSurfaces.AppendElement(FrameSurface{aId, transform, clipRect,
|
||||
ToSamplingFilter(aImageRendering)});
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::MaybeRequestAllowFrameRecording(
|
||||
bool aWillRecord) {
|
||||
mCompositor->RequestAllowFrameRecording(aWillRecord);
|
||||
}
|
||||
|
||||
bool RenderCompositorLayersSWGL::MaybeRecordFrame(
|
||||
layers::CompositionRecorder& aRecorder) {
|
||||
layers::WindowLMC window(mCompositor);
|
||||
gfx::IntSize size = GetBufferSize().ToUnknownSize();
|
||||
RefPtr<layers::profiler_screenshots::RenderSource> snapshot =
|
||||
window.GetWindowContents(size);
|
||||
if (!snapshot) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<layers::profiler_screenshots::AsyncReadbackBuffer> buffer =
|
||||
window.CreateAsyncReadbackBuffer(size);
|
||||
buffer->CopyFrom(snapshot);
|
||||
|
||||
RefPtr<layers::RecordedFrame> frame =
|
||||
new RenderCompositorRecordedFrame(TimeStamp::Now(), std::move(buffer));
|
||||
aRecorder.RecordFrame(frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RenderCompositorLayersSWGL::MaybeGrabScreenshot(
|
||||
const gfx::IntSize& aWindowSize) {
|
||||
layers::WindowLMC window(mCompositor);
|
||||
mProfilerScreenshotGrabber.MaybeGrabScreenshot(window, aWindowSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderCompositorLayersSWGL::MaybeProcessScreenshotQueue() {
|
||||
mProfilerScreenshotGrabber.MaybeProcessQueue();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,189 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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_RENDERCOMPOSITOR_Layers_H
|
||||
#define MOZILLA_GFX_RENDERCOMPOSITOR_Layers_H
|
||||
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/ScreenshotGrabber.h"
|
||||
#include "mozilla/webrender/RenderCompositor.h"
|
||||
#include "mozilla/webrender/RenderTextureHost.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace wr {
|
||||
|
||||
class SurfaceD3D11SWGL;
|
||||
|
||||
class RenderCompositorLayersSWGL : public RenderCompositor {
|
||||
public:
|
||||
static UniquePtr<RenderCompositor> Create(
|
||||
RefPtr<widget::CompositorWidget>&& aWidget, nsACString& aError);
|
||||
|
||||
RenderCompositorLayersSWGL(layers::Compositor* aCompositor,
|
||||
RefPtr<widget::CompositorWidget>&& aWidget,
|
||||
void* aContext);
|
||||
virtual ~RenderCompositorLayersSWGL();
|
||||
|
||||
void* swgl() const override { return mContext; }
|
||||
|
||||
bool MakeCurrent() override;
|
||||
|
||||
bool BeginFrame() override;
|
||||
void CancelFrame() override;
|
||||
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
|
||||
|
||||
bool SurfaceOriginIsTopLeft() override { return true; }
|
||||
|
||||
LayoutDeviceIntSize GetBufferSize() override;
|
||||
|
||||
// Should we support this?
|
||||
bool SupportsExternalBufferTextures() const override { return false; }
|
||||
|
||||
layers::WebRenderBackend BackendType() const override {
|
||||
return layers::WebRenderBackend::SOFTWARE;
|
||||
}
|
||||
|
||||
// Interface for wr::Compositor
|
||||
CompositorCapabilities GetCompositorCapabilities() override;
|
||||
|
||||
bool ShouldUseNativeCompositor() override { return true; }
|
||||
|
||||
void CompositorBeginFrame() override {}
|
||||
void CompositorEndFrame() override;
|
||||
void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
|
||||
wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect) override;
|
||||
void Unbind() override;
|
||||
bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
|
||||
wr::DeviceIntRect aValidRect, void** aData,
|
||||
int32_t* aStride) override;
|
||||
void UnmapTile() override;
|
||||
void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
|
||||
wr::DeviceIntSize aTileSize, bool aIsOpaque) override;
|
||||
void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque) override;
|
||||
void DestroySurface(NativeSurfaceId aId) override;
|
||||
void CreateTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) override;
|
||||
void DestroyTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) override;
|
||||
void AttachExternalImage(wr::NativeSurfaceId aId,
|
||||
wr::ExternalImageId aExternalImage) override;
|
||||
void AddSurface(wr::NativeSurfaceId aId,
|
||||
const wr::CompositorSurfaceTransform& aTransform,
|
||||
wr::DeviceIntRect aClipRect,
|
||||
wr::ImageRendering aImageRendering) override;
|
||||
void EnableNativeCompositor(bool aEnable) override {}
|
||||
void DeInit() override {}
|
||||
|
||||
void MaybeRequestAllowFrameRecording(bool aWillRecord) override;
|
||||
bool MaybeRecordFrame(layers::CompositionRecorder& aRecorder) override;
|
||||
bool MaybeGrabScreenshot(const gfx::IntSize& aWindowSize) override;
|
||||
bool MaybeProcessScreenshotQueue() override;
|
||||
|
||||
// TODO: Screenshots etc
|
||||
|
||||
struct TileKey {
|
||||
TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {}
|
||||
|
||||
int32_t mX;
|
||||
int32_t mY;
|
||||
};
|
||||
|
||||
// Each tile retains a texture, and a DataSourceSurface of the
|
||||
// same size. We draw into the source surface, and then copy the
|
||||
// changed area into the texture.
|
||||
class Tile {
|
||||
public:
|
||||
Tile() = default;
|
||||
virtual ~Tile() = default;
|
||||
|
||||
virtual bool Map(wr::DeviceIntRect aDirtyRect, wr::DeviceIntRect aValidRect,
|
||||
void** aData, int32_t* aStride) = 0;
|
||||
virtual void Unmap(const gfx::IntRect& aDirtyRect) = 0;
|
||||
virtual layers::DataTextureSource* GetTextureSource() = 0;
|
||||
virtual bool IsValid() = 0;
|
||||
|
||||
gfx::Rect mValidRect;
|
||||
|
||||
struct KeyHashFn {
|
||||
std::size_t operator()(const TileKey& aId) const {
|
||||
return HashGeneric(aId.mX, aId.mY);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class Surface {
|
||||
public:
|
||||
explicit Surface(wr::DeviceIntSize aTileSize, bool aIsOpaque)
|
||||
: mTileSize(aTileSize), mIsOpaque(aIsOpaque) {}
|
||||
virtual ~Surface() {}
|
||||
|
||||
gfx::IntSize TileSize() {
|
||||
return gfx::IntSize(mTileSize.width, mTileSize.height);
|
||||
}
|
||||
virtual SurfaceD3D11SWGL* AsSurfaceD3D11SWGL() { return nullptr; }
|
||||
|
||||
// External images can change size depending on which image
|
||||
// is attached, so mTileSize will be 0,0 when mIsExternal
|
||||
// is true.
|
||||
wr::DeviceIntSize mTileSize;
|
||||
bool mIsOpaque;
|
||||
bool mIsExternal = false;
|
||||
std::unordered_map<TileKey, UniquePtr<Tile>, Tile::KeyHashFn> mTiles;
|
||||
RefPtr<RenderTextureHost> mExternalImage;
|
||||
|
||||
struct IdHashFn {
|
||||
std::size_t operator()(const wr::NativeSurfaceId& aId) const {
|
||||
return HashGeneric(wr::AsUint64(aId));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
static gfx::SamplingFilter ToSamplingFilter(
|
||||
wr::ImageRendering aImageRendering);
|
||||
|
||||
protected:
|
||||
// The set of surfaces added to be composited for the current frame
|
||||
struct FrameSurface {
|
||||
wr::NativeSurfaceId mId;
|
||||
gfx::Matrix4x4 mTransform;
|
||||
gfx::IntRect mClipRect;
|
||||
gfx::SamplingFilter mFilter;
|
||||
};
|
||||
|
||||
virtual void HandleExternalImage(RenderTextureHost* aExternalImage,
|
||||
FrameSurface& aFrameSurface) = 0;
|
||||
virtual UniquePtr<RenderCompositorLayersSWGL::Surface> DoCreateSurface(
|
||||
wr::DeviceIntSize aTileSize, bool aIsOpaque);
|
||||
virtual UniquePtr<RenderCompositorLayersSWGL::Tile> DoCreateTile(
|
||||
Surface* aSurface) = 0;
|
||||
|
||||
RefPtr<layers::Compositor> mCompositor;
|
||||
void* mContext = nullptr;
|
||||
|
||||
std::unordered_map<wr::NativeSurfaceId, UniquePtr<Surface>, Surface::IdHashFn>
|
||||
mSurfaces;
|
||||
|
||||
// Temporary state held between MapTile and UnmapTile
|
||||
Tile* mCurrentTile = nullptr;
|
||||
gfx::IntRect mCurrentTileDirty;
|
||||
wr::NativeTileId mCurrentTileId;
|
||||
|
||||
nsTArray<FrameSurface> mFrameSurfaces;
|
||||
bool mInFrame = false;
|
||||
|
||||
layers::ScreenshotGrabber mProfilerScreenshotGrabber;
|
||||
};
|
||||
|
||||
static inline bool operator==(const RenderCompositorLayersSWGL::TileKey& a0,
|
||||
const RenderCompositorLayersSWGL::TileKey& a1) {
|
||||
return a0.mX == a1.mX && a0.mY == a1.mY;
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -12,6 +12,7 @@ EXPORTS.mozilla.webrender += [
|
|||
"RenderBufferTextureHostSWGL.h",
|
||||
"RenderCompositor.h",
|
||||
"RenderCompositorEGL.h",
|
||||
"RenderCompositorLayersSWGL.h",
|
||||
"RenderCompositorOGL.h",
|
||||
"RenderCompositorSWGL.h",
|
||||
"RenderEGLImageTextureHost.h",
|
||||
|
@ -35,6 +36,7 @@ UNIFIED_SOURCES += [
|
|||
"RenderBufferTextureHostSWGL.cpp",
|
||||
"RenderCompositor.cpp",
|
||||
"RenderCompositorEGL.cpp",
|
||||
"RenderCompositorLayersSWGL.cpp",
|
||||
"RenderCompositorOGL.cpp",
|
||||
"RenderCompositorSWGL.cpp",
|
||||
"RenderEGLImageTextureHost.cpp",
|
||||
|
|
Загрузка…
Ссылка в новой задаче