зеркало из https://github.com/mozilla/gecko-dev.git
Backout changeset 07d34812bdee, b879d413ce2d, 0c59eeb18700 due to android opengl regression on chrome pages; r=backout
This commit is contained in:
Родитель
19a852d5de
Коммит
a6b3246fd0
|
@ -191,96 +191,40 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
|
|||
renderRegion = &visibleRegion;
|
||||
}
|
||||
|
||||
mTexImage->BeginTileIteration();
|
||||
if (mTexImageOnWhite) {
|
||||
mTexImageOnWhite->BeginTileIteration();
|
||||
NS_ASSERTION(mTexImageOnWhite->GetTileRect() == mTexImage->GetTileRect(), "component alpha textures should be the same size.");
|
||||
}
|
||||
nsIntRegion region(*renderRegion);
|
||||
nsIntPoint origin = GetOriginOffset();
|
||||
region.MoveBy(-origin); // translate into TexImage space, buffer origin might not be at texture (0,0)
|
||||
|
||||
// Figure out the intersecting draw region
|
||||
nsIntSize texSize = mTexImage->GetSize();
|
||||
nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height);
|
||||
textureRect.MoveBy(region.GetBounds().TopLeft());
|
||||
nsIntRegion subregion;
|
||||
subregion.And(region, textureRect);
|
||||
if (subregion.IsEmpty()) // Region is empty, nothing to draw
|
||||
return;
|
||||
|
||||
nsIntRegion screenRects;
|
||||
nsIntRegion regionRects;
|
||||
|
||||
// Collect texture/screen coordinates for drawing
|
||||
nsIntRegionRectIterator iter(subregion);
|
||||
while (const nsIntRect* iterRect = iter.Next()) {
|
||||
nsIntRect regionRect = *iterRect;
|
||||
nsIntRect screenRect = regionRect;
|
||||
screenRect.MoveBy(origin);
|
||||
|
||||
screenRects.Or(screenRects, screenRect);
|
||||
regionRects.Or(regionRects, regionRect);
|
||||
}
|
||||
|
||||
mTexImage->BeginTileIteration();
|
||||
if (mTexImageOnWhite) {
|
||||
NS_ASSERTION(mTexImage->GetTileCount() == mTexImageOnWhite->GetTileCount(),
|
||||
"Tile count mismatch on component alpha texture");
|
||||
mTexImageOnWhite->BeginTileIteration();
|
||||
}
|
||||
|
||||
bool usingTiles = (mTexImage->GetTileCount() > 1);
|
||||
do {
|
||||
if (mTexImageOnWhite) {
|
||||
NS_ASSERTION(mTexImageOnWhite->GetTileRect() == mTexImage->GetTileRect(), "component alpha textures should be the same size.");
|
||||
nsIntRect textureRect = mTexImage->GetTileRect();
|
||||
textureRect.MoveBy(region.GetBounds().x, region.GetBounds().y);
|
||||
nsIntRegion subregion(region);
|
||||
subregion.And(region, textureRect); // region this texture is visible in
|
||||
if (subregion.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsIntRect tileRect = mTexImage->GetTileRect();
|
||||
|
||||
// Bind textures.
|
||||
TextureImage::ScopedBindTexture texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
TextureImage::ScopedBindTexture texOnWhiteBind(mTexImageOnWhite, LOCAL_GL_TEXTURE1);
|
||||
|
||||
// Draw texture. If we're using tiles, we do repeating manually, as texture
|
||||
// repeat would cause each individual tile to repeat instead of the
|
||||
// compound texture as a whole. This involves drawing at most 4 sections,
|
||||
// 2 for each axis that has texture repeat.
|
||||
for (int y = 0; y < (usingTiles ? 2 : 1); y++) {
|
||||
for (int x = 0; x < (usingTiles ? 2 : 1); x++) {
|
||||
nsIntRect currentTileRect(tileRect);
|
||||
currentTileRect.MoveBy(x * texSize.width, y * texSize.height);
|
||||
nsIntRegionRectIterator iter(subregion);
|
||||
while (const nsIntRect *iterRect = iter.Next()) {
|
||||
nsIntRect regionRect = *iterRect; // one rectangle of this texture's region
|
||||
// translate into the correct place for this texture sub-region
|
||||
nsIntRect screenRect = regionRect;
|
||||
screenRect.MoveBy(origin);
|
||||
program->SetLayerQuadRect(screenRect);
|
||||
|
||||
nsIntRegionRectIterator screenIter(screenRects);
|
||||
nsIntRegionRectIterator regionIter(regionRects);
|
||||
|
||||
const nsIntRect* screenRect;
|
||||
const nsIntRect* regionRect;
|
||||
while ((screenRect = screenIter.Next()) &&
|
||||
(regionRect = regionIter.Next())) {
|
||||
nsIntRect tileScreenRect(*screenRect);
|
||||
nsIntRect tileRegionRect(*regionRect);
|
||||
|
||||
// When we're using tiles, find the intersection between the tile
|
||||
// rect and this region rect. Tiling is then handled by the
|
||||
// outer for-loops and modifying the tile rect.
|
||||
if (usingTiles) {
|
||||
tileScreenRect.MoveBy(-origin);
|
||||
tileScreenRect = tileScreenRect.Intersect(currentTileRect);
|
||||
tileScreenRect.MoveBy(origin);
|
||||
|
||||
if (tileScreenRect.IsEmpty())
|
||||
continue;
|
||||
|
||||
tileRegionRect = regionRect->Intersect(currentTileRect);
|
||||
tileRegionRect.MoveBy(-currentTileRect.TopLeft());
|
||||
}
|
||||
|
||||
program->SetLayerQuadRect(tileScreenRect);
|
||||
aManager->BindAndDrawQuadWithTextureRect(program, tileRegionRect,
|
||||
tileRect.Size(),
|
||||
mTexImage->GetWrapMode());
|
||||
}
|
||||
}
|
||||
regionRect.MoveBy(-mTexImage->GetTileRect().TopLeft()); // get region of tile
|
||||
aManager->BindAndDrawQuadWithTextureRect(program, regionRect,
|
||||
textureRect.Size(),
|
||||
mTexImage->GetWrapMode());
|
||||
}
|
||||
|
||||
if (mTexImageOnWhite)
|
||||
mTexImageOnWhite->NextTile();
|
||||
} while (mTexImage->NextTile());
|
||||
}
|
||||
|
||||
|
@ -847,18 +791,6 @@ ShadowBufferOGL::Upload(gfxASurface* aUpdate, const nsIntRegion& aUpdated,
|
|||
nsIntPoint visTopLeft = mLayer->GetVisibleRegion().GetBounds().TopLeft();
|
||||
destRegion.MoveBy(-visTopLeft);
|
||||
|
||||
// Correct for rotation
|
||||
destRegion.MoveBy(aRotation);
|
||||
nsIntRect destBounds = destRegion.GetBounds();
|
||||
destRegion.MoveBy((destBounds.x >= size.width) ? -size.width : 0,
|
||||
(destBounds.y >= size.height) ? -size.height : 0);
|
||||
|
||||
// There's code to make sure that updated regions don't cross rotation
|
||||
// boundaries, so assert here that this is the case
|
||||
NS_ASSERTION(((destBounds.x % size.width) + destBounds.width <= size.width) &&
|
||||
((destBounds.y % size.height) + destBounds.height <= size.height),
|
||||
"Updated region lies across rotation boundaries!");
|
||||
|
||||
// NB: this gfxContext must not escape EndUpdate() below
|
||||
mTexImage->DirectUpdate(aUpdate, destRegion);
|
||||
|
||||
|
|
|
@ -575,8 +575,20 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
|
|||
NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?");
|
||||
|
||||
// determine the region the client will need to repaint
|
||||
GetUpdateRegion(aRegion);
|
||||
mUpdateRegion = aRegion;
|
||||
ImageFormat format =
|
||||
(GetContentType() == gfxASurface::CONTENT_COLOR) ?
|
||||
gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32;
|
||||
if (mTextureState != Valid)
|
||||
{
|
||||
// if the texture hasn't been initialized yet, or something important
|
||||
// changed, we need to recreate our backing surface and force the
|
||||
// client to paint everything
|
||||
mUpdateRegion = nsIntRect(nsIntPoint(0, 0), mSize);
|
||||
} else {
|
||||
mUpdateRegion = aRegion;
|
||||
}
|
||||
|
||||
aRegion = mUpdateRegion;
|
||||
|
||||
nsIntRect rgnSize = mUpdateRegion.GetBounds();
|
||||
if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(rgnSize)) {
|
||||
|
@ -584,10 +596,7 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ImageFormat format =
|
||||
(GetContentType() == gfxASurface::CONTENT_COLOR) ?
|
||||
gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32;
|
||||
mUpdateSurface =
|
||||
mUpdateSurface =
|
||||
GetSurfaceForUpdate(gfxIntSize(rgnSize.width, rgnSize.height), format);
|
||||
|
||||
if (!mUpdateSurface || mUpdateSurface->CairoStatus()) {
|
||||
|
@ -600,16 +609,6 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
|
|||
return mUpdateSurface;
|
||||
}
|
||||
|
||||
void
|
||||
BasicTextureImage::GetUpdateRegion(nsIntRegion& aForRegion)
|
||||
{
|
||||
// if the texture hasn't been initialized yet, or something important
|
||||
// changed, we need to recreate our backing surface and force the
|
||||
// client to paint everything
|
||||
if (mTextureState != Valid)
|
||||
aForRegion = nsIntRect(nsIntPoint(0, 0), mSize);
|
||||
}
|
||||
|
||||
void
|
||||
BasicTextureImage::EndUpdate()
|
||||
{
|
||||
|
@ -730,9 +729,10 @@ TiledTextureImage::~TiledTextureImage()
|
|||
bool
|
||||
TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */)
|
||||
{
|
||||
nsIntRect bounds = aRegion.GetBounds();
|
||||
nsIntRegion region;
|
||||
if (mTextureState != Valid) {
|
||||
nsIntRect bounds = nsIntRect(0, 0, mSize.width, mSize.height);
|
||||
bounds = nsIntRect(0, 0, mSize.width, mSize.height);
|
||||
region = nsIntRegion(bounds);
|
||||
} else {
|
||||
region = aRegion;
|
||||
|
@ -740,8 +740,8 @@ TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion,
|
|||
|
||||
PRBool result = PR_TRUE;
|
||||
for (unsigned i = 0; i < mImages.Length(); i++) {
|
||||
int xPos = (i % mColumns) * mTileSize;
|
||||
int yPos = (i / mColumns) * mTileSize;
|
||||
unsigned int xPos = (i % mColumns) * mTileSize;
|
||||
unsigned int yPos = (i / mColumns) * mTileSize;
|
||||
nsIntRegion tileRegion;
|
||||
tileRegion.And(region, nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize())); // intersect with tile
|
||||
if (tileRegion.IsEmpty())
|
||||
|
@ -757,66 +757,25 @@ TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion,
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
TiledTextureImage::GetUpdateRegion(nsIntRegion& aForRegion)
|
||||
{
|
||||
if (mTextureState != Valid) {
|
||||
// if the texture hasn't been initialized yet, or something important
|
||||
// changed, we need to recreate our backing surface and force the
|
||||
// client to paint everything
|
||||
aForRegion = nsIntRect(nsIntPoint(0, 0), mSize);
|
||||
return;
|
||||
}
|
||||
|
||||
nsIntRegion newRegion;
|
||||
|
||||
// We need to query each texture with the region it will be drawing and
|
||||
// set aForRegion to be the combination of all of these regions
|
||||
for (unsigned i = 0; i < mImages.Length(); i++) {
|
||||
int xPos = (i % mColumns) * mTileSize;
|
||||
int yPos = (i / mColumns) * mTileSize;
|
||||
nsIntRect imageRect = nsIntRect(nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize()));
|
||||
|
||||
if (aForRegion.Intersects(imageRect)) {
|
||||
// Make a copy of the region
|
||||
nsIntRegion subRegion;
|
||||
subRegion.And(aForRegion, imageRect);
|
||||
// Translate it into tile-space
|
||||
subRegion.MoveBy(-xPos, -yPos);
|
||||
// Query region
|
||||
mImages[i]->GetUpdateRegion(subRegion);
|
||||
// Translate back
|
||||
subRegion.MoveBy(xPos, yPos);
|
||||
// Add to the accumulated region
|
||||
newRegion.Or(newRegion, subRegion);
|
||||
}
|
||||
}
|
||||
|
||||
aForRegion = newRegion;
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(!mInUpdate, "nested update");
|
||||
mInUpdate = PR_TRUE;
|
||||
|
||||
// Note, we don't call GetUpdateRegion here as if the updated region is
|
||||
// fully contained in a single tile, we get to avoid iterating through
|
||||
// the tiles again (and a little copying).
|
||||
if (mTextureState != Valid)
|
||||
{
|
||||
// if the texture hasn't been initialized yet, or something important
|
||||
// changed, we need to recreate our backing surface and force the
|
||||
// client to paint everything
|
||||
aRegion = nsIntRect(nsIntPoint(0, 0), mSize);
|
||||
mUpdateRegion = nsIntRect(nsIntPoint(0, 0), mSize);
|
||||
} else {
|
||||
mUpdateRegion = aRegion;
|
||||
}
|
||||
|
||||
nsIntRect bounds = aRegion.GetBounds();
|
||||
|
||||
for (unsigned i = 0; i < mImages.Length(); i++) {
|
||||
int xPos = (i % mColumns) * mTileSize;
|
||||
int yPos = (i / mColumns) * mTileSize;
|
||||
unsigned int xPos = (i % mColumns) * mTileSize;
|
||||
unsigned int yPos = (i / mColumns) * mTileSize;
|
||||
nsIntRegion imageRegion = nsIntRegion(nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize()));
|
||||
|
||||
// a single Image can handle this update request
|
||||
|
@ -827,10 +786,6 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
|
|||
nsRefPtr<gfxASurface> surface = mImages[i]->BeginUpdate(aRegion);
|
||||
// caller expects container space
|
||||
aRegion.MoveBy(xPos, yPos);
|
||||
// Correct the device offset
|
||||
gfxPoint offset = surface->GetDeviceOffset();
|
||||
surface->SetDeviceOffset(gfxPoint(offset.x - xPos,
|
||||
offset.y - yPos));
|
||||
// we don't have a temp surface
|
||||
mUpdateSurface = nsnull;
|
||||
// remember which image to EndUpdate
|
||||
|
@ -838,21 +793,15 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
|
|||
return surface.get();
|
||||
}
|
||||
}
|
||||
|
||||
// Get the real updated region, taking into account the capabilities of
|
||||
// each TextureImage tile
|
||||
GetUpdateRegion(aRegion);
|
||||
mUpdateRegion = aRegion;
|
||||
bounds = aRegion.GetBounds();
|
||||
|
||||
// update covers multiple Images - create a temp surface to paint in
|
||||
gfxASurface::gfxImageFormat format =
|
||||
(GetContentType() == gfxASurface::CONTENT_COLOR) ?
|
||||
gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32;
|
||||
|
||||
nsIntRect bounds = aRegion.GetBounds();
|
||||
mUpdateSurface = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height), gfxASurface::ContentFromFormat(format));
|
||||
mUpdateSurface->SetDeviceOffset(gfxPoint(-bounds.x, -bounds.y));
|
||||
|
||||
return mUpdateSurface;
|
||||
}
|
||||
|
||||
|
@ -871,10 +820,9 @@ TiledTextureImage::EndUpdate()
|
|||
|
||||
// upload tiles from temp surface
|
||||
for (unsigned i = 0; i < mImages.Length(); i++) {
|
||||
int xPos = (i % mColumns) * mTileSize;
|
||||
int yPos = (i / mColumns) * mTileSize;
|
||||
unsigned int xPos = (i % mColumns) * mTileSize;
|
||||
unsigned int yPos = (i / mColumns) * mTileSize;
|
||||
nsIntRect imageRect = nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize());
|
||||
|
||||
nsIntRegion subregion;
|
||||
subregion.And(mUpdateRegion, imageRect);
|
||||
if (subregion.IsEmpty())
|
||||
|
@ -894,7 +842,6 @@ TiledTextureImage::EndUpdate()
|
|||
mInUpdate = PR_FALSE;
|
||||
mShaderType = mImages[0]->GetShaderProgramType();
|
||||
mIsRGBFormat = mImages[0]->IsRGB();
|
||||
mTextureState = Valid;
|
||||
}
|
||||
|
||||
void TiledTextureImage::BeginTileIteration()
|
||||
|
@ -954,11 +901,6 @@ void TiledTextureImage::Resize(const nsIntSize& aSize)
|
|||
mTextureState = Allocated;
|
||||
}
|
||||
|
||||
PRUint32 TiledTextureImage::GetTileCount()
|
||||
{
|
||||
return mImages.Length();
|
||||
}
|
||||
|
||||
PRBool
|
||||
GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
|
||||
{
|
||||
|
|
|
@ -193,15 +193,6 @@ public:
|
|||
* followed by EndUpdate().
|
||||
*/
|
||||
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion) = 0;
|
||||
/**
|
||||
* Retrieves the region that will require updating, given a
|
||||
* region that needs to be updated. This can be used for
|
||||
* making decisions about updating before calling BeginUpdate().
|
||||
*
|
||||
* |aRegion| is an inout param.
|
||||
*/
|
||||
virtual void GetUpdateRegion(nsIntRegion& aForRegion) {
|
||||
};
|
||||
/**
|
||||
* Finish the active update and synchronize with the server, if
|
||||
* necessary.
|
||||
|
@ -227,11 +218,6 @@ public:
|
|||
};
|
||||
|
||||
virtual GLuint GetTextureID() = 0;
|
||||
|
||||
virtual PRUint32 GetTileCount() {
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set this TextureImage's size, and ensure a texture has been
|
||||
* allocated. Must not be called between BeginUpdate and EndUpdate.
|
||||
|
@ -362,7 +348,6 @@ public:
|
|||
virtual void BindTexture(GLenum aTextureUnit);
|
||||
|
||||
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
|
||||
virtual void GetUpdateRegion(nsIntRegion& aForRegion);
|
||||
virtual void EndUpdate();
|
||||
virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
|
||||
virtual GLuint GetTextureID() { return mTexture; };
|
||||
|
@ -407,10 +392,8 @@ public:
|
|||
~TiledTextureImage();
|
||||
void DumpDiv();
|
||||
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
|
||||
virtual void GetUpdateRegion(nsIntRegion& aForRegion);
|
||||
virtual void EndUpdate();
|
||||
virtual void Resize(const nsIntSize& aSize);
|
||||
virtual PRUint32 GetTileCount();
|
||||
virtual void BeginTileIteration();
|
||||
virtual PRBool NextTile();
|
||||
virtual nsIntRect GetTileRect();
|
||||
|
|
|
@ -1232,28 +1232,27 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void GetUpdateRegion(nsIntRegion& aForRegion)
|
||||
{
|
||||
if (mTextureState != Valid) {
|
||||
// if the texture hasn't been initialized yet, force the
|
||||
// client to paint everything
|
||||
aForRegion = nsIntRect(nsIntPoint(0, 0), mSize);
|
||||
} else if (!mBackingSurface) {
|
||||
// We can only draw a rectangle, not subregions due to
|
||||
// the way that our texture upload functions work. If
|
||||
// needed, we /could/ do multiple texture uploads if we have
|
||||
// non-overlapping rects, but that's a tradeoff.
|
||||
aForRegion = nsIntRegion(mUpdateRect);
|
||||
}
|
||||
}
|
||||
|
||||
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?");
|
||||
|
||||
// determine the region the client will need to repaint
|
||||
GetUpdateRegion(aRegion);
|
||||
mUpdateRect = aRegion.GetBounds();
|
||||
if (mTextureState != Valid) {
|
||||
// if the texture hasn't been initialized yet, force the
|
||||
// client to paint everything
|
||||
mUpdateRect = nsIntRect(nsIntPoint(0, 0), mSize);
|
||||
//printf_stderr("v Forcing full paint\n");
|
||||
aRegion = nsIntRegion(mUpdateRect);
|
||||
} else {
|
||||
mUpdateRect = aRegion.GetBounds();
|
||||
if (!mBackingSurface) {
|
||||
// We can only draw a rectangle, not subregions due to
|
||||
// the way that our texture upload functions work. If
|
||||
// needed, we /could/ do multiple texture uploads if we have
|
||||
// non-overlapping rects, but that's a tradeoff.
|
||||
aRegion = nsIntRegion(mUpdateRect);
|
||||
}
|
||||
}
|
||||
|
||||
//printf_stderr("BeginUpdate with updateRect [%d %d %d %d]\n", mUpdateRect.x, mUpdateRect.y, mUpdateRect.width, mUpdateRect.height);
|
||||
if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче