mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
263
gfx/layers/client/SingleTiledContentClient.cpp
Normal file
263
gfx/layers/client/SingleTiledContentClient.cpp
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "mozilla/layers/SingleTiledContentClient.h"
|
||||
|
||||
#include "ClientTiledPaintedLayer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
||||
SingleTiledContentClient::SingleTiledContentClient(ClientTiledPaintedLayer& aPaintedLayer,
|
||||
ClientLayerManager* aManager)
|
||||
: TiledContentClient(aManager, "Single")
|
||||
{
|
||||
MOZ_COUNT_CTOR(SingleTiledContentClient);
|
||||
|
||||
mTiledBuffer = new ClientSingleTiledLayerBuffer(aPaintedLayer, *this, aManager);
|
||||
}
|
||||
|
||||
void
|
||||
SingleTiledContentClient::ClearCachedResources()
|
||||
{
|
||||
CompositableClient::ClearCachedResources();
|
||||
mTiledBuffer->DiscardBuffers();
|
||||
}
|
||||
|
||||
void
|
||||
SingleTiledContentClient::UpdatedBuffer(TiledBufferType aType)
|
||||
{
|
||||
mForwarder->UseTiledLayerBuffer(this, mTiledBuffer->GetSurfaceDescriptorTiles());
|
||||
mTiledBuffer->ClearPaintedRegion();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
SingleTiledContentClient::ClientSupportsLayerSize(const gfx::IntSize& aSize, ClientLayerManager* aManager)
|
||||
{
|
||||
int32_t maxTextureSize = aManager->GetMaxTextureSize();
|
||||
return aSize.width <= maxTextureSize && aSize.height <= maxTextureSize;
|
||||
}
|
||||
|
||||
ClientSingleTiledLayerBuffer::ClientSingleTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer,
|
||||
CompositableClient& aCompositableClient,
|
||||
ClientLayerManager* aManager)
|
||||
: ClientTiledLayerBuffer(aPaintedLayer, aCompositableClient)
|
||||
, mWasLastPaintProgressive(false)
|
||||
, mFormat(gfx::SurfaceFormat::UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ClientSingleTiledLayerBuffer::ReleaseTiles()
|
||||
{
|
||||
if (!mTile.IsPlaceholderTile()) {
|
||||
mTile.DiscardBuffers();
|
||||
}
|
||||
mTile.SetTextureAllocator(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
ClientSingleTiledLayerBuffer::DiscardBuffers()
|
||||
{
|
||||
if (!mTile.IsPlaceholderTile()) {
|
||||
mTile.DiscardFrontBuffer();
|
||||
mTile.DiscardBackBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceDescriptorTiles
|
||||
ClientSingleTiledLayerBuffer::GetSurfaceDescriptorTiles()
|
||||
{
|
||||
InfallibleTArray<TileDescriptor> tiles;
|
||||
|
||||
TileDescriptor tileDesc = mTile.GetTileDescriptor();
|
||||
tiles.AppendElement(tileDesc);
|
||||
mTile.mUpdateRect = gfx::IntRect();
|
||||
|
||||
return SurfaceDescriptorTiles(mValidRegion,
|
||||
tiles,
|
||||
mTilingOrigin,
|
||||
mSize,
|
||||
0, 0, 1, 1,
|
||||
1.0,
|
||||
mFrameResolution.xScale,
|
||||
mFrameResolution.yScale,
|
||||
mWasLastPaintProgressive);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
ClientSingleTiledLayerBuffer::GetTextureClient()
|
||||
{
|
||||
MOZ_ASSERT(mFormat != gfx::SurfaceFormat::UNKNOWN);
|
||||
return mCompositableClient.CreateTextureClientForDrawing(
|
||||
gfx::ImageFormatToSurfaceFormat(mFormat), mSize, BackendSelector::Content,
|
||||
TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD);
|
||||
}
|
||||
|
||||
void
|
||||
ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
|
||||
const nsIntRegion& aPaintRegion,
|
||||
const nsIntRegion& aDirtyRegion,
|
||||
LayerManager::DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
bool aIsProgressive)
|
||||
{
|
||||
mWasLastPaintProgressive = aIsProgressive;
|
||||
|
||||
// Compare layer valid region size to current backbuffer size, discard if not matching.
|
||||
gfx::IntSize size = aNewValidRegion.GetBounds().Size();
|
||||
gfx::IntPoint origin = aNewValidRegion.GetBounds().TopLeft();
|
||||
nsIntRegion paintRegion = aPaintRegion;
|
||||
|
||||
RefPtr<TextureClient> discardedFrontBuffer = nullptr;
|
||||
RefPtr<TextureClient> discardedFrontBufferOnWhite = nullptr;
|
||||
nsIntRegion discardedValidRegion;
|
||||
|
||||
if (mSize != size ||
|
||||
mTilingOrigin != origin) {
|
||||
discardedFrontBuffer = mTile.mFrontBuffer;
|
||||
discardedFrontBufferOnWhite = mTile.mFrontBufferOnWhite;
|
||||
discardedValidRegion = mValidRegion;
|
||||
|
||||
TILING_LOG("TILING %p: Single-tile valid region changed. Discarding buffers.\n", &mPaintedLayer)
|
||||
;
|
||||
ResetPaintedAndValidState();
|
||||
mSize = size;
|
||||
mTilingOrigin = origin;
|
||||
paintRegion = aNewValidRegion;
|
||||
}
|
||||
|
||||
SurfaceMode mode;
|
||||
gfxContentType content = GetContentType(&mode);
|
||||
mFormat = gfxPlatform::GetPlatform()->OptimalFormatForContent(content);
|
||||
|
||||
if (mTile.IsPlaceholderTile()) {
|
||||
mTile.SetTextureAllocator(this);
|
||||
}
|
||||
|
||||
// The dirty region relative to the top-left of the tile.
|
||||
nsIntRegion tileDirtyRegion = paintRegion.MovedBy(-mTilingOrigin);
|
||||
|
||||
nsIntRegion extraPainted;
|
||||
RefPtr<TextureClient> backBufferOnWhite;
|
||||
RefPtr<TextureClient> backBuffer =
|
||||
mTile.GetBackBuffer(mCompositableClient,
|
||||
tileDirtyRegion,
|
||||
content, mode,
|
||||
extraPainted,
|
||||
&backBufferOnWhite);
|
||||
|
||||
mTile.mUpdateRect = tileDirtyRegion.GetBounds().Union(extraPainted.GetBounds());
|
||||
|
||||
extraPainted.MoveBy(mTilingOrigin);
|
||||
extraPainted.And(extraPainted, aNewValidRegion);
|
||||
mPaintedRegion.OrWith(paintRegion);
|
||||
mPaintedRegion.OrWith(extraPainted);
|
||||
|
||||
if (!backBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<gfx::DrawTarget> dt = backBuffer->BorrowDrawTarget();
|
||||
RefPtr<gfx::DrawTarget> dtOnWhite;
|
||||
if (backBufferOnWhite) {
|
||||
dtOnWhite = backBufferOnWhite->BorrowDrawTarget();
|
||||
}
|
||||
|
||||
if (mode != SurfaceMode::SURFACE_OPAQUE) {
|
||||
for (auto iter = tileDirtyRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const gfx::IntRect& rect = iter.Get();
|
||||
if (dtOnWhite) {
|
||||
dt->FillRect(gfx::Rect(rect.x, rect.y, rect.width, rect.height),
|
||||
gfx::ColorPattern(gfx::Color(0.0, 0.0, 0.0, 1.0)));
|
||||
dtOnWhite->FillRect(gfx::Rect(rect.x, rect.y, rect.width, rect.height),
|
||||
gfx::ColorPattern(gfx::Color(1.0, 1.0, 1.0, 1.0)));
|
||||
} else {
|
||||
dt->ClearRect(gfx::Rect(rect.x, rect.y, rect.width, rect.height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the old frontbuffer was discarded then attempt to copy what we
|
||||
// can from it to the new backbuffer.
|
||||
if (discardedFrontBuffer) {
|
||||
nsIntRegion copyableRegion;
|
||||
copyableRegion.And(aNewValidRegion, discardedValidRegion);
|
||||
copyableRegion.SubOut(aDirtyRegion);
|
||||
|
||||
if (!copyableRegion.IsEmpty()) {
|
||||
TextureClientAutoLock frontLock(discardedFrontBuffer,
|
||||
OpenMode::OPEN_READ);
|
||||
if (frontLock.Succeeded()) {
|
||||
for (auto iter = copyableRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const gfx::IntRect rect = iter.Get() - discardedValidRegion.GetBounds().TopLeft();
|
||||
const gfx::IntPoint dest = iter.Get().TopLeft() - mTilingOrigin;
|
||||
discardedFrontBuffer->CopyToTextureClient(backBuffer, &rect, &dest);
|
||||
}
|
||||
}
|
||||
|
||||
if (discardedFrontBufferOnWhite && backBufferOnWhite) {
|
||||
TextureClientAutoLock frontOnWhiteLock(discardedFrontBufferOnWhite,
|
||||
OpenMode::OPEN_READ);
|
||||
if (frontOnWhiteLock.Succeeded()) {
|
||||
for (auto iter = copyableRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const gfx::IntRect rect = iter.Get() - discardedValidRegion.GetBounds().TopLeft();
|
||||
const gfx::IntPoint dest = iter.Get().TopLeft() - mTilingOrigin;
|
||||
|
||||
discardedFrontBufferOnWhite->CopyToTextureClient(backBufferOnWhite,
|
||||
&rect, &dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TILING_LOG("TILING %p: Region copied from discarded frontbuffer %s\n", &mPaintedLayer, Stringify(copyableRegion).c_str());
|
||||
|
||||
// We don't need to repaint valid content that was just copied.
|
||||
paintRegion.SubOut(copyableRegion);
|
||||
}
|
||||
}
|
||||
|
||||
if (dtOnWhite) {
|
||||
dt = gfx::Factory::CreateDualDrawTarget(dt, dtOnWhite);
|
||||
dtOnWhite = nullptr;
|
||||
}
|
||||
|
||||
{
|
||||
RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(dt);
|
||||
if (!ctx) {
|
||||
gfxDevCrash(gfx::LogReason::InvalidContext) << "SingleTiledContextClient context problem " << gfx::hexa(dt);
|
||||
return;
|
||||
}
|
||||
ctx->SetMatrix(ctx->CurrentMatrix().Translate(-mTilingOrigin.x, -mTilingOrigin.y));
|
||||
|
||||
aCallback(&mPaintedLayer, ctx, paintRegion, paintRegion, DrawRegionClip::DRAW, nsIntRegion(), aCallbackData);
|
||||
}
|
||||
|
||||
// Mark the area we just drew into the back buffer as invalid in the front buffer as they're
|
||||
// now out of sync.
|
||||
mTile.mInvalidFront.OrWith(tileDirtyRegion);
|
||||
|
||||
// The new buffer is now validated, remove the dirty region from it.
|
||||
mTile.mInvalidBack.SubOut(tileDirtyRegion);
|
||||
|
||||
dt = nullptr;
|
||||
|
||||
mTile.Flip();
|
||||
UnlockTile(mTile);
|
||||
|
||||
if (backBuffer->HasIntermediateBuffer()) {
|
||||
// If our new buffer has an internal buffer, we don't want to keep another
|
||||
// TextureClient around unnecessarily, so discard the back-buffer.
|
||||
mTile.DiscardBackBuffer();
|
||||
}
|
||||
|
||||
mValidRegion = aNewValidRegion;
|
||||
mLastPaintSurfaceMode = mode;
|
||||
mLastPaintContentType = content;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
Loading…
Add table
Add a link
Reference in a new issue