mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 783368 - Add a low precision buffer to tiled thebes layers. r=bgirard,kats
If there is a critical display port set, render the area outside it into a lower precision buffer.
This commit is contained in:
parent
221843e04f
commit
f068580516
@ -143,6 +143,7 @@ public:
|
||||
Update(nsIntRegion(), nsIntRegion());
|
||||
mResolution = aResolution;
|
||||
}
|
||||
bool IsLowPrecision() const { return mResolution < 1; }
|
||||
|
||||
protected:
|
||||
// The implementor should call Update() to change
|
||||
|
@ -276,6 +276,7 @@ public:
|
||||
virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
void SetRepeatTransaction() { mRepeatTransaction = true; }
|
||||
bool GetRepeatTransaction() { return mRepeatTransaction; }
|
||||
|
||||
bool IsRepeatTransaction() { return mIsRepeatTransaction; }
|
||||
|
||||
|
@ -264,7 +264,8 @@ RoundedTransformViewportBounds(const gfx::Rect& aViewport,
|
||||
}
|
||||
|
||||
bool
|
||||
BasicTiledThebesLayer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInvalidRegion,
|
||||
BasicTiledThebesLayer::ComputeProgressiveUpdateRegion(BasicTiledLayerBuffer& aTiledBuffer,
|
||||
const nsIntRegion& aInvalidRegion,
|
||||
const nsIntRegion& aOldValidRegion,
|
||||
nsIntRegion& aRegionToPaint,
|
||||
const gfx3DMatrix& aTransform,
|
||||
@ -274,6 +275,11 @@ BasicTiledThebesLayer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInvali
|
||||
{
|
||||
aRegionToPaint = aInvalidRegion;
|
||||
|
||||
// If this is a low precision buffer, we force progressive updates. The
|
||||
// assumption is that the contents is less important, so visual coherency
|
||||
// is lower priority than speed.
|
||||
bool forceProgressive = aTiledBuffer.IsLowPrecision();
|
||||
|
||||
// Find out if we have any non-stale content to update.
|
||||
nsIntRegion freshRegion;
|
||||
if (!mFirstPaint) {
|
||||
@ -316,20 +322,20 @@ BasicTiledThebesLayer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInvali
|
||||
nsIntRect paintBounds = aRegionToPaint.GetBounds();
|
||||
|
||||
int startX, incX, startY, incY;
|
||||
int tileLength = mTiledBuffer.GetScaledTileLength();
|
||||
int tileLength = aTiledBuffer.GetScaledTileLength();
|
||||
if (aScrollOffset.x >= mLastScrollOffset.x) {
|
||||
startX = mTiledBuffer.RoundDownToTileEdge(paintBounds.x);
|
||||
startX = aTiledBuffer.RoundDownToTileEdge(paintBounds.x);
|
||||
incX = tileLength;
|
||||
} else {
|
||||
startX = mTiledBuffer.RoundDownToTileEdge(paintBounds.XMost() - 1);
|
||||
startX = aTiledBuffer.RoundDownToTileEdge(paintBounds.XMost() - 1);
|
||||
incX = -tileLength;
|
||||
}
|
||||
|
||||
if (aScrollOffset.y >= mLastScrollOffset.y) {
|
||||
startY = mTiledBuffer.RoundDownToTileEdge(paintBounds.y);
|
||||
startY = aTiledBuffer.RoundDownToTileEdge(paintBounds.y);
|
||||
incY = tileLength;
|
||||
} else {
|
||||
startY = mTiledBuffer.RoundDownToTileEdge(paintBounds.YMost() - 1);
|
||||
startY = aTiledBuffer.RoundDownToTileEdge(paintBounds.YMost() - 1);
|
||||
incY = -tileLength;
|
||||
}
|
||||
|
||||
@ -361,19 +367,68 @@ BasicTiledThebesLayer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInvali
|
||||
// in one go by repeating this work without calling the painted
|
||||
// callback. The remaining content is then drawn tile-by-tile in
|
||||
// multiple transactions.
|
||||
if (paintVisible && drawingStale) {
|
||||
if (!forceProgressive && paintVisible && drawingStale) {
|
||||
repeatImmediately = true;
|
||||
} else {
|
||||
BasicManager()->SetRepeatTransaction();
|
||||
}
|
||||
} else {
|
||||
// The transaction is completed, store the last scroll offset.
|
||||
mLastScrollOffset = aScrollOffset;
|
||||
}
|
||||
|
||||
return repeatImmediately;
|
||||
}
|
||||
|
||||
bool
|
||||
BasicTiledThebesLayer::ProgressiveUpdate(BasicTiledLayerBuffer& aTiledBuffer,
|
||||
nsIntRegion& aValidRegion,
|
||||
nsIntRegion& aInvalidRegion,
|
||||
const nsIntRegion& aOldValidRegion,
|
||||
const gfx3DMatrix& aTransform,
|
||||
const gfx::Point& aScrollOffset,
|
||||
const gfxSize& aResolution,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
bool repeat = false;
|
||||
do {
|
||||
// Compute the region that should be updated. Repeat as many times as
|
||||
// is required.
|
||||
nsIntRegion regionToPaint;
|
||||
repeat = ComputeProgressiveUpdateRegion(aTiledBuffer,
|
||||
aInvalidRegion,
|
||||
aOldValidRegion,
|
||||
regionToPaint,
|
||||
aTransform,
|
||||
aScrollOffset,
|
||||
aResolution,
|
||||
repeat);
|
||||
|
||||
// There's no further work to be done, return if nothing has been
|
||||
// drawn, or give what has been drawn to the shadow layer to upload.
|
||||
if (regionToPaint.IsEmpty()) {
|
||||
if (repeat) {
|
||||
break;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep track of what we're about to refresh.
|
||||
aValidRegion.Or(aValidRegion, regionToPaint);
|
||||
|
||||
// aValidRegion may have been altered by InvalidateRegion, but we still
|
||||
// want to display stale content until it gets progressively updated.
|
||||
// Create a region that includes stale content.
|
||||
nsIntRegion validOrStale;
|
||||
validOrStale.Or(aValidRegion, aOldValidRegion);
|
||||
|
||||
// Paint the computed region and subtract it from the invalid region.
|
||||
aTiledBuffer.PaintThebes(this, validOrStale, regionToPaint, aCallback, aCallbackData);
|
||||
aInvalidRegion.Sub(aInvalidRegion, regionToPaint);
|
||||
} while (repeat);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
@ -394,6 +449,9 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
if (mTiledBuffer.HasFormatChanged(this)) {
|
||||
mValidRegion = nsIntRegion();
|
||||
}
|
||||
if (mLowPrecisionTiledBuffer.HasFormatChanged(this)) {
|
||||
mLowPrecisionValidRegion = nsIntRegion();
|
||||
}
|
||||
|
||||
nsIntRegion invalidRegion = mVisibleRegion;
|
||||
invalidRegion.Sub(invalidRegion, mValidRegion);
|
||||
@ -438,6 +496,14 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
resolution.height *= metrics.mResolution.height;
|
||||
}
|
||||
|
||||
// Calculate the scroll offset since the last transaction.
|
||||
gfx::Point scrollOffset(0, 0);
|
||||
Layer* primaryScrollable = BasicManager()->GetPrimaryScrollableLayer();
|
||||
if (primaryScrollable) {
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
scrollOffset = metrics.mScrollOffset;
|
||||
}
|
||||
|
||||
// Only draw progressively when the resolution is unchanged.
|
||||
if (gfxPlatform::UseProgressiveTilePainting() &&
|
||||
!BasicManager()->HasShadowTarget() &&
|
||||
@ -450,7 +516,6 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
if (!layerDisplayPort.IsEmpty()) {
|
||||
oldValidRegion.And(oldValidRegion, layerDisplayPort);
|
||||
}
|
||||
mTiledBuffer.ClearPaintedRegion();
|
||||
|
||||
// Make sure that tiles that fall outside of the visible region are
|
||||
// discarded on the first update.
|
||||
@ -461,52 +526,11 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the scroll offset since the last transaction.
|
||||
gfx::Point scrollOffset(0, 0);
|
||||
Layer* primaryScrollable = BasicManager()->GetPrimaryScrollableLayer();
|
||||
if (primaryScrollable) {
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
scrollOffset = metrics.mScrollOffset;
|
||||
}
|
||||
|
||||
bool repeat = false;
|
||||
do {
|
||||
// Compute the region that should be updated. Repeat as many times as
|
||||
// is required.
|
||||
nsIntRegion regionToPaint;
|
||||
repeat = ComputeProgressiveUpdateRegion(invalidRegion,
|
||||
oldValidRegion,
|
||||
regionToPaint,
|
||||
transform,
|
||||
scrollOffset,
|
||||
resolution,
|
||||
repeat);
|
||||
|
||||
// There's no further work to be done, return if nothing has been
|
||||
// drawn, or give what has been drawn to the shadow layer to upload.
|
||||
if (regionToPaint.IsEmpty()) {
|
||||
if (repeat) {
|
||||
break;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep track of what we're about to refresh.
|
||||
mValidRegion.Or(mValidRegion, regionToPaint);
|
||||
|
||||
// mValidRegion would have been altered by InvalidateRegion, but we still
|
||||
// want to display stale content until it gets progressively updated.
|
||||
// Create a region that includes stale content.
|
||||
nsIntRegion validOrStale;
|
||||
validOrStale.Or(mValidRegion, oldValidRegion);
|
||||
|
||||
// Paint the computed region and subtract it from the invalid region.
|
||||
mTiledBuffer.PaintThebes(this, validOrStale, regionToPaint, aCallback, aCallbackData);
|
||||
invalidRegion.Sub(invalidRegion, regionToPaint);
|
||||
} while (repeat);
|
||||
if (!ProgressiveUpdate(mTiledBuffer, mValidRegion, invalidRegion,
|
||||
oldValidRegion, transform, scrollOffset, resolution,
|
||||
aCallback, aCallbackData))
|
||||
return;
|
||||
} else {
|
||||
mTiledBuffer.ClearPaintedRegion();
|
||||
mTiledBuffer.SetFrameResolution(resolution);
|
||||
mValidRegion = mVisibleRegion;
|
||||
if (!layerDisplayPort.IsEmpty()) {
|
||||
@ -530,6 +554,67 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
BasicTiledLayerBuffer *heapCopy = new BasicTiledLayerBuffer(mTiledBuffer);
|
||||
|
||||
BasicManager()->PaintedTiledLayerBuffer(BasicManager()->Hold(this), heapCopy);
|
||||
mTiledBuffer.ClearPaintedRegion();
|
||||
|
||||
// If we have a critical display-port defined, render the full display-port
|
||||
// progressively in the low-precision tiled buffer.
|
||||
bool clearedLowPrecision = false;
|
||||
bool updatedLowPrecision = false;
|
||||
if (!criticalDisplayPort.IsEmpty() &&
|
||||
!nsIntRegion(layerDisplayPort).Contains(mVisibleRegion)) {
|
||||
nsIntRegion oldValidRegion = mLowPrecisionTiledBuffer.GetValidRegion();
|
||||
oldValidRegion.And(oldValidRegion, mVisibleRegion);
|
||||
|
||||
// If the frame resolution has changed, invalidate the buffer
|
||||
if (mLowPrecisionTiledBuffer.GetFrameResolution() != resolution) {
|
||||
if (!mLowPrecisionValidRegion.IsEmpty()) {
|
||||
clearedLowPrecision = true;
|
||||
}
|
||||
oldValidRegion.SetEmpty();
|
||||
mLowPrecisionValidRegion.SetEmpty();
|
||||
mLowPrecisionTiledBuffer.SetFrameResolution(resolution);
|
||||
}
|
||||
|
||||
// Invalidate previously valid content that is no longer visible
|
||||
if (!BasicManager()->IsRepeatTransaction()) {
|
||||
mLowPrecisionValidRegion.And(mLowPrecisionValidRegion, mVisibleRegion);
|
||||
}
|
||||
|
||||
nsIntRegion lowPrecisionInvalidRegion;
|
||||
lowPrecisionInvalidRegion.Sub(mVisibleRegion, mLowPrecisionValidRegion);
|
||||
|
||||
if (!lowPrecisionInvalidRegion.IsEmpty()) {
|
||||
updatedLowPrecision =
|
||||
ProgressiveUpdate(mLowPrecisionTiledBuffer, mLowPrecisionValidRegion,
|
||||
lowPrecisionInvalidRegion, oldValidRegion, transform,
|
||||
scrollOffset, resolution, aCallback, aCallbackData);
|
||||
}
|
||||
} else if (!mLowPrecisionValidRegion.IsEmpty()) {
|
||||
// Clear the low precision tiled buffer
|
||||
clearedLowPrecision = true;
|
||||
mLowPrecisionValidRegion.SetEmpty();
|
||||
mLowPrecisionTiledBuffer.PaintThebes(this, mLowPrecisionValidRegion,
|
||||
mLowPrecisionValidRegion, aCallback,
|
||||
aCallbackData);
|
||||
}
|
||||
|
||||
// We send a Painted callback if we clear the valid region of the low
|
||||
// precision buffer, so that the shadow buffer's valid region can be updated
|
||||
// and the associated resources can be freed.
|
||||
if (clearedLowPrecision || updatedLowPrecision) {
|
||||
mLowPrecisionTiledBuffer.ReadLock();
|
||||
BasicTiledLayerBuffer *heapCopy = new BasicTiledLayerBuffer(mLowPrecisionTiledBuffer);
|
||||
|
||||
// The GL layer manager uses the buffer resolution to distinguish calls
|
||||
// to PaintedTiledLayerBuffer.
|
||||
BasicManager()->PaintedTiledLayerBuffer(BasicManager()->Hold(this), heapCopy);
|
||||
mLowPrecisionTiledBuffer.ClearPaintedRegion();
|
||||
}
|
||||
|
||||
// The transaction is completed, store the last scroll offset.
|
||||
if (!BasicManager()->GetRepeatTransaction()) {
|
||||
mLastScrollOffset = scrollOffset;
|
||||
}
|
||||
mFirstPaint = false;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "BasicImplData.h"
|
||||
#include <algorithm>
|
||||
|
||||
#define LOW_PRECISION_RESOLUTION 0.25
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
@ -166,6 +168,7 @@ public:
|
||||
, mFirstPaint(true)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicTiledThebesLayer);
|
||||
mLowPrecisionTiledBuffer.SetResolution(LOW_PRECISION_RESOLUTION);
|
||||
}
|
||||
|
||||
~BasicTiledThebesLayer()
|
||||
@ -179,6 +182,7 @@ public:
|
||||
virtual void InvalidateRegion(const nsIntRegion& aRegion) {
|
||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
||||
mValidRegion.Sub(mValidRegion, aRegion);
|
||||
mLowPrecisionValidRegion.Sub(mLowPrecisionValidRegion, aRegion);
|
||||
}
|
||||
|
||||
// Shadow methods
|
||||
@ -220,7 +224,7 @@ private:
|
||||
* at once to maintain visual coherency.
|
||||
*
|
||||
* aInvalidRegion is the current invalid region.
|
||||
* aOldValidRegion is the valid region of mTiledBuffer at the beginning of the
|
||||
* aOldValidRegion is the valid region of aTiledBuffer at the beginning of the
|
||||
* current transaction.
|
||||
* aRegionToPaint will be filled with the region to update. This may be empty,
|
||||
* which indicates that there is no more work to do.
|
||||
@ -234,7 +238,8 @@ private:
|
||||
* Returns true if it should be called again, false otherwise. In the case
|
||||
* that aRegionToPaint is empty, this will return aIsRepeated for convenience.
|
||||
*/
|
||||
bool ComputeProgressiveUpdateRegion(const nsIntRegion& aInvalidRegion,
|
||||
bool ComputeProgressiveUpdateRegion(BasicTiledLayerBuffer& aTiledBuffer,
|
||||
const nsIntRegion& aInvalidRegion,
|
||||
const nsIntRegion& aOldValidRegion,
|
||||
nsIntRegion& aRegionToPaint,
|
||||
const gfx3DMatrix& aTransform,
|
||||
@ -242,8 +247,23 @@ private:
|
||||
const gfxSize& aResolution,
|
||||
bool aIsRepeated);
|
||||
|
||||
/**
|
||||
* Performs a progressive update of a given tiled buffer.
|
||||
*/
|
||||
bool ProgressiveUpdate(BasicTiledLayerBuffer& aTiledBuffer,
|
||||
nsIntRegion& aValidRegion,
|
||||
nsIntRegion& aInvalidRegion,
|
||||
const nsIntRegion& aOldValidRegion,
|
||||
const gfx3DMatrix& aTransform,
|
||||
const gfx::Point& aScrollOffset,
|
||||
const gfxSize& aResolution,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
// Members
|
||||
BasicTiledLayerBuffer mTiledBuffer;
|
||||
BasicTiledLayerBuffer mLowPrecisionTiledBuffer;
|
||||
nsIntRegion mLowPrecisionValidRegion;
|
||||
gfx::Point mLastScrollOffset;
|
||||
bool mFirstPaint;
|
||||
};
|
||||
|
@ -116,7 +116,10 @@ TiledThebesLayerOGL::TiledThebesLayerOGL(LayerManagerOGL *aManager)
|
||||
: ShadowThebesLayer(aManager, nullptr)
|
||||
, LayerOGL(aManager)
|
||||
, mVideoMemoryTiledBuffer(aManager->gl())
|
||||
, mLowPrecisionVideoMemoryTiledBuffer(aManager->gl())
|
||||
, mReusableTileStore(nullptr)
|
||||
, mPendingUpload(false)
|
||||
, mPendingLowPrecisionUpload(false)
|
||||
{
|
||||
mImplData = static_cast<LayerOGL*>(this);
|
||||
}
|
||||
@ -124,6 +127,7 @@ TiledThebesLayerOGL::TiledThebesLayerOGL(LayerManagerOGL *aManager)
|
||||
TiledThebesLayerOGL::~TiledThebesLayerOGL()
|
||||
{
|
||||
mMainMemoryTiledBuffer.ReadUnlock();
|
||||
mLowPrecisionMainMemoryTiledBuffer.ReadUnlock();
|
||||
if (mReusableTileStore)
|
||||
delete mReusableTileStore;
|
||||
}
|
||||
@ -140,18 +144,54 @@ TiledThebesLayerOGL::MemoryPressure()
|
||||
void
|
||||
TiledThebesLayerOGL::PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* mTiledBuffer)
|
||||
{
|
||||
mMainMemoryTiledBuffer.ReadUnlock();
|
||||
mMainMemoryTiledBuffer = *mTiledBuffer;
|
||||
if (mTiledBuffer->IsLowPrecision()) {
|
||||
mLowPrecisionMainMemoryTiledBuffer.ReadUnlock();
|
||||
mLowPrecisionMainMemoryTiledBuffer = *mTiledBuffer;
|
||||
mLowPrecisionRegionToUpload.Or(mLowPrecisionRegionToUpload,
|
||||
mLowPrecisionMainMemoryTiledBuffer.GetPaintedRegion());
|
||||
mLowPrecisionMainMemoryTiledBuffer.ClearPaintedRegion();
|
||||
mPendingLowPrecisionUpload = true;
|
||||
} else {
|
||||
mMainMemoryTiledBuffer.ReadUnlock();
|
||||
mMainMemoryTiledBuffer = *mTiledBuffer;
|
||||
mRegionToUpload.Or(mRegionToUpload, mMainMemoryTiledBuffer.GetPaintedRegion());
|
||||
mMainMemoryTiledBuffer.ClearPaintedRegion();
|
||||
mPendingUpload = true;
|
||||
}
|
||||
|
||||
// TODO: Remove me once Bug 747811 lands.
|
||||
delete mTiledBuffer;
|
||||
mRegionToUpload.Or(mRegionToUpload, mMainMemoryTiledBuffer.GetPaintedRegion());
|
||||
mMainMemoryTiledBuffer.ClearPaintedRegion();
|
||||
}
|
||||
|
||||
void
|
||||
TiledThebesLayerOGL::ProcessLowPrecisionUploadQueue()
|
||||
{
|
||||
if (!mPendingLowPrecisionUpload)
|
||||
return;
|
||||
|
||||
mLowPrecisionRegionToUpload.And(mLowPrecisionRegionToUpload,
|
||||
mLowPrecisionMainMemoryTiledBuffer.GetValidRegion());
|
||||
// XXX The aResolution parameter of Upload is unused here - this is normally
|
||||
// set so that ReusableTileStoreOGL knows the frame resolution of tiles
|
||||
// it's harvesting.
|
||||
mLowPrecisionVideoMemoryTiledBuffer.SetResolution(
|
||||
mLowPrecisionMainMemoryTiledBuffer.GetResolution());
|
||||
mLowPrecisionVideoMemoryTiledBuffer.Upload(&mLowPrecisionMainMemoryTiledBuffer,
|
||||
mLowPrecisionMainMemoryTiledBuffer.GetValidRegion(),
|
||||
mLowPrecisionRegionToUpload, gfxSize(1, 1));
|
||||
nsIntRegion validRegion = mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion();
|
||||
|
||||
mLowPrecisionMainMemoryTiledBuffer.ReadUnlock();
|
||||
|
||||
mLowPrecisionMainMemoryTiledBuffer = BasicTiledLayerBuffer();
|
||||
mLowPrecisionRegionToUpload = nsIntRegion();
|
||||
mPendingLowPrecisionUpload = false;
|
||||
}
|
||||
|
||||
void
|
||||
TiledThebesLayerOGL::ProcessUploadQueue()
|
||||
{
|
||||
if (mRegionToUpload.IsEmpty())
|
||||
if (!mPendingUpload)
|
||||
return;
|
||||
|
||||
// We should only be retaining old tiles if we're not fixed position.
|
||||
@ -194,7 +234,7 @@ TiledThebesLayerOGL::ProcessUploadQueue()
|
||||
mVideoMemoryTiledBuffer.Upload(&mMainMemoryTiledBuffer,
|
||||
mMainMemoryTiledBuffer.GetValidRegion(),
|
||||
mRegionToUpload, resolution);
|
||||
mVideoMemoryTiledBuffer.SetResolution(mMainMemoryTiledBuffer.GetResolution());
|
||||
|
||||
mValidRegion = mVideoMemoryTiledBuffer.GetValidRegion();
|
||||
|
||||
mMainMemoryTiledBuffer.ReadUnlock();
|
||||
@ -205,7 +245,7 @@ TiledThebesLayerOGL::ProcessUploadQueue()
|
||||
// tile by tile.
|
||||
mMainMemoryTiledBuffer = BasicTiledLayerBuffer();
|
||||
mRegionToUpload = nsIntRegion();
|
||||
|
||||
mPendingUpload = false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -243,26 +283,15 @@ TiledThebesLayerOGL::RenderTile(const TiledTexture& aTile,
|
||||
}
|
||||
|
||||
void
|
||||
TiledThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset)
|
||||
TiledThebesLayerOGL::RenderLayerBuffer(TiledLayerBufferOGL& aLayerBuffer,
|
||||
const nsIntRegion& aValidRegion,
|
||||
const nsIntPoint& aOffset,
|
||||
const nsIntRegion& aMaskRegion)
|
||||
{
|
||||
gl()->MakeCurrent();
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
ProcessUploadQueue();
|
||||
|
||||
Layer* maskLayer = GetMaskLayer();
|
||||
|
||||
// Render old tiles to fill in gaps we haven't had the time to render yet.
|
||||
if (mReusableTileStore) {
|
||||
mReusableTileStore->DrawTiles(this,
|
||||
mVideoMemoryTiledBuffer.GetValidRegion(),
|
||||
mVideoMemoryTiledBuffer.GetFrameResolution(),
|
||||
GetEffectiveTransform(), aOffset, maskLayer);
|
||||
}
|
||||
|
||||
// Render valid tiles.
|
||||
const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion();
|
||||
const nsIntRect visibleRect = visibleRegion.GetBounds();
|
||||
float resolution = mVideoMemoryTiledBuffer.GetResolution();
|
||||
float resolution = aLayerBuffer.GetResolution();
|
||||
gfx3DMatrix transform = GetEffectiveTransform();
|
||||
transform.Scale(1/resolution, 1/resolution, 1);
|
||||
|
||||
@ -270,30 +299,34 @@ TiledThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOf
|
||||
uint32_t tileX = 0;
|
||||
for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) {
|
||||
rowCount++;
|
||||
int32_t tileStartX = mVideoMemoryTiledBuffer.GetTileStart(x);
|
||||
int32_t w = mVideoMemoryTiledBuffer.GetScaledTileLength() - tileStartX;
|
||||
int32_t tileStartX = aLayerBuffer.GetTileStart(x);
|
||||
int32_t w = aLayerBuffer.GetScaledTileLength() - tileStartX;
|
||||
if (x + w > visibleRect.x + visibleRect.width)
|
||||
w = visibleRect.x + visibleRect.width - x;
|
||||
int tileY = 0;
|
||||
for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) {
|
||||
int32_t tileStartY = mVideoMemoryTiledBuffer.GetTileStart(y);
|
||||
int32_t h = mVideoMemoryTiledBuffer.GetScaledTileLength() - tileStartY;
|
||||
int32_t tileStartY = aLayerBuffer.GetTileStart(y);
|
||||
int32_t h = aLayerBuffer.GetScaledTileLength() - tileStartY;
|
||||
if (y + h > visibleRect.y + visibleRect.height)
|
||||
h = visibleRect.y + visibleRect.height - y;
|
||||
|
||||
TiledTexture tileTexture = mVideoMemoryTiledBuffer.
|
||||
GetTile(nsIntPoint(mVideoMemoryTiledBuffer.RoundDownToTileEdge(x),
|
||||
mVideoMemoryTiledBuffer.RoundDownToTileEdge(y)));
|
||||
if (tileTexture != mVideoMemoryTiledBuffer.GetPlaceholderTile()) {
|
||||
TiledTexture tileTexture = aLayerBuffer.
|
||||
GetTile(nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x),
|
||||
aLayerBuffer.RoundDownToTileEdge(y)));
|
||||
if (tileTexture != aLayerBuffer.GetPlaceholderTile()) {
|
||||
nsIntRegion tileDrawRegion = nsIntRegion(nsIntRect(x, y, w, h));
|
||||
tileDrawRegion.And(tileDrawRegion, mValidRegion);
|
||||
tileDrawRegion.ScaleRoundOut(resolution, resolution);
|
||||
tileDrawRegion.And(tileDrawRegion, aValidRegion);
|
||||
tileDrawRegion.Sub(tileDrawRegion, aMaskRegion);
|
||||
|
||||
nsIntPoint tileOffset((x - tileStartX) * resolution,
|
||||
(y - tileStartY) * resolution);
|
||||
uint32_t tileSize = mVideoMemoryTiledBuffer.GetTileLength();
|
||||
RenderTile(tileTexture, transform, aOffset, tileDrawRegion,
|
||||
tileOffset, nsIntSize(tileSize, tileSize), maskLayer);
|
||||
if (!tileDrawRegion.IsEmpty()) {
|
||||
tileDrawRegion.ScaleRoundOut(resolution, resolution);
|
||||
|
||||
nsIntPoint tileOffset((x - tileStartX) * resolution,
|
||||
(y - tileStartY) * resolution);
|
||||
uint32_t tileSize = aLayerBuffer.GetTileLength();
|
||||
RenderTile(tileTexture, transform, aOffset, tileDrawRegion,
|
||||
tileOffset, nsIntSize(tileSize, tileSize), maskLayer);
|
||||
}
|
||||
}
|
||||
tileY++;
|
||||
y += h;
|
||||
@ -303,5 +336,28 @@ TiledThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOf
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TiledThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset)
|
||||
{
|
||||
gl()->MakeCurrent();
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
ProcessUploadQueue();
|
||||
ProcessLowPrecisionUploadQueue();
|
||||
|
||||
// Render old tiles to fill in gaps we haven't had the time to render yet.
|
||||
if (mReusableTileStore) {
|
||||
mReusableTileStore->DrawTiles(this,
|
||||
mVideoMemoryTiledBuffer.GetValidRegion(),
|
||||
mVideoMemoryTiledBuffer.GetFrameResolution(),
|
||||
GetEffectiveTransform(), aOffset, GetMaskLayer());
|
||||
}
|
||||
|
||||
// Render valid tiles.
|
||||
RenderLayerBuffer(mLowPrecisionVideoMemoryTiledBuffer,
|
||||
mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion(),
|
||||
aOffset, mValidRegion);
|
||||
RenderLayerBuffer(mVideoMemoryTiledBuffer, mValidRegion, aOffset, nsIntRegion());
|
||||
}
|
||||
|
||||
} // mozilla
|
||||
} // layers
|
||||
|
@ -131,6 +131,7 @@ public:
|
||||
}
|
||||
void PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* mTiledBuffer);
|
||||
void ProcessUploadQueue();
|
||||
void ProcessLowPrecisionUploadQueue();
|
||||
|
||||
void MemoryPressure();
|
||||
|
||||
@ -144,10 +145,20 @@ public:
|
||||
Layer* aMaskLayer);
|
||||
|
||||
private:
|
||||
void RenderLayerBuffer(TiledLayerBufferOGL& aLayerBuffer,
|
||||
const nsIntRegion& aValidRegion,
|
||||
const nsIntPoint& aOffset,
|
||||
const nsIntRegion& aMaskRegion);
|
||||
|
||||
nsIntRegion mRegionToUpload;
|
||||
nsIntRegion mLowPrecisionRegionToUpload;
|
||||
BasicTiledLayerBuffer mMainMemoryTiledBuffer;
|
||||
BasicTiledLayerBuffer mLowPrecisionMainMemoryTiledBuffer;
|
||||
TiledLayerBufferOGL mVideoMemoryTiledBuffer;
|
||||
TiledLayerBufferOGL mLowPrecisionVideoMemoryTiledBuffer;
|
||||
ReusableTileStoreOGL* mReusableTileStore;
|
||||
bool mPendingUpload : 1;
|
||||
bool mPendingLowPrecisionUpload : 1;
|
||||
};
|
||||
|
||||
} // layers
|
||||
|
@ -2745,7 +2745,26 @@ Tab.prototype = {
|
||||
Math.abs(displayPort.y - this._oldDisplayPort.y) > epsilon ||
|
||||
Math.abs(displayPort.width - this._oldDisplayPort.width) > epsilon ||
|
||||
Math.abs(displayPort.height - this._oldDisplayPort.height) > epsilon) {
|
||||
cwu.setDisplayPortForElement(displayPort.x, displayPort.y, displayPort.width, displayPort.height, element);
|
||||
// Set the display-port to be 4x the size of the critical display-port,
|
||||
// on each dimension, giving us a 0.25x lower precision buffer around the
|
||||
// critical display-port. Spare area is *not* redistributed to the other
|
||||
// axis, as display-list building and invalidation cost scales with the
|
||||
// size of the display-port.
|
||||
let pageRect = cwu.getRootBounds();
|
||||
let pageXMost = pageRect.right - geckoScrollX;
|
||||
let pageYMost = pageRect.bottom - geckoScrollY;
|
||||
|
||||
let dpW = Math.min(pageRect.right - pageRect.left, displayPort.width * 4);
|
||||
let dpH = Math.min(pageRect.bottom - pageRect.top, displayPort.height * 4);
|
||||
|
||||
let dpX = Math.min(Math.max(displayPort.x - displayPort.width * 1.5,
|
||||
pageRect.left - geckoScrollX), pageXMost - dpW);
|
||||
let dpY = Math.min(Math.max(displayPort.y - displayPort.height * 1.5,
|
||||
pageRect.top - geckoScrollY), pageYMost - dpH);
|
||||
cwu.setDisplayPortForElement(dpX, dpY, dpW, dpH, element);
|
||||
cwu.setCriticalDisplayPortForElement(displayPort.x, displayPort.y,
|
||||
displayPort.width, displayPort.height,
|
||||
element);
|
||||
}
|
||||
|
||||
this._oldDisplayPort = displayPort;
|
||||
|
Loading…
Reference in New Issue
Block a user