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:
Chris Lord 2012-11-21 22:34:19 +00:00
parent 221843e04f
commit f068580516
7 changed files with 290 additions and 97 deletions

View File

@ -143,6 +143,7 @@ public:
Update(nsIntRegion(), nsIntRegion());
mResolution = aResolution;
}
bool IsLowPrecision() const { return mResolution < 1; }
protected:
// The implementor should call Update() to change

View File

@ -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; }

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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

View File

@ -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

View File

@ -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;