From 919f7180110f58427746b23d07fddd3bcdf6b4b9 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Wed, 21 Nov 2012 22:34:18 +0000 Subject: [PATCH] Bug 783368 - Add resolution to TiledLayerBuffer. r=bgirard Add the concept of resolution to TiledLayerBuffer and add support for it in BasicTiledThebesLayer and TiledThebesLayerOGL. --- gfx/layers/TiledLayerBuffer.h | 79 +++++++++++++++------- gfx/layers/basic/BasicTiledThebesLayer.cpp | 48 ++++++++----- gfx/layers/basic/BasicTiledThebesLayer.h | 6 +- gfx/layers/opengl/ReusableTileStoreOGL.cpp | 3 + gfx/layers/opengl/TiledThebesLayerOGL.cpp | 22 +++--- gfx/layers/opengl/TiledThebesLayerOGL.h | 6 +- 6 files changed, 108 insertions(+), 56 deletions(-) diff --git a/gfx/layers/TiledLayerBuffer.h b/gfx/layers/TiledLayerBuffer.h index d149e0787a8d..a6a67db0754d 100644 --- a/gfx/layers/TiledLayerBuffer.h +++ b/gfx/layers/TiledLayerBuffer.h @@ -29,7 +29,9 @@ namespace layers { // template pattern. // // Tiles are aligned to a grid with one of the grid points at (0,0) and other -// grid points spaced evenly in the x- and y-directions by GetTileLength(). +// grid points spaced evenly in the x- and y-directions by GetTileLength() +// multiplied by mResolution. GetScaledTileLength() provides convenience for +// accessing these values. // // This tile buffer stores a valid region, which defines the areas that have // up-to-date content. The contents of tiles within this region will be reused @@ -66,6 +68,11 @@ namespace layers { // void SwapTiles(Tile& aTileA, Tile& aTileB); // // Swaps two tiles. +// +// The contents of the tile buffer will be rendered at the resolution specified +// in mResolution, which can be altered with SetResolution. The resolution +// should always be a factor of the tile length, to avoid tiles covering +// non-integer amounts of pixels. template class TiledLayerBuffer @@ -74,20 +81,23 @@ public: TiledLayerBuffer() : mRetainedWidth(0) , mRetainedHeight(0) + , mResolution(1) {} ~TiledLayerBuffer() {} - // Given a tile origin aligned to a multiple of GetTileLength(), + // Given a tile origin aligned to a multiple of GetScaledTileLength, // return the tile that describes that region. // NOTE: To get the valid area of that tile you must intersect - // (aTileOrigin.x, aTileOrigin.y, GetTileLength(), GetTileLength()) + // (aTileOrigin.x, aTileOrigin.y, + // GetScaledTileLength(), GetScaledTileLength()) // and GetValidRegion() to get the area of the tile that is valid. Tile GetTile(const nsIntPoint& aTileOrigin) const; // Given a tile x, y relative to the top left of the layer, this function // will return the tile for - // (x*GetTileLength(), y*GetTileLength(), GetTileLength(), GetTileLength()) + // (x*GetScaledTileLength(), y*GetScaledTileLength(), + // GetScaledTileLength(), GetScaledTileLength()) Tile GetTile(int x, int y) const; // This operates the same as GetTile(aTileOrigin), but will also replace the @@ -101,6 +111,7 @@ public: bool RemoveTile(int x, int y, Tile& aRemovedTile); uint16_t GetTileLength() const { return TILEDLAYERBUFFER_TILE_SIZE; } + uint32_t GetScaledTileLength() const { return TILEDLAYERBUFFER_TILE_SIZE / mResolution; } unsigned int GetTileCount() const { return mRetainedTiles.Length(); } @@ -110,13 +121,29 @@ public: // Given a position i, this function returns the position inside the current tile. int GetTileStart(int i) const { - return (i >= 0) ? (i % GetTileLength()) - : ((GetTileLength() - (-i % GetTileLength())) % GetTileLength()); + return (i >= 0) ? (i % GetScaledTileLength()) + : ((GetScaledTileLength() - (-i % GetScaledTileLength())) % + GetScaledTileLength()); } // Rounds the given coordinate down to the nearest tile boundary. int RoundDownToTileEdge(int aX) const { return aX - GetTileStart(aX); } + // Get and set draw scaling. mResolution affects the resolution at which the + // contents of the buffer are drawn. mResolution has no effect on the + // coordinate space of the valid region, but does affect the size of an + // individual tile's rect in relation to the valid region. + // Setting the resolution will invalidate the buffer. + float GetResolution() const { return mResolution; } + void SetResolution(float aResolution) { + if (mResolution == aResolution) { + return; + } + + Update(nsIntRegion(), nsIntRegion()); + mResolution = aResolution; + } + protected: // The implementor should call Update() to change // the new valid region. This implementation will call @@ -132,11 +159,13 @@ protected: * stored as column major with the same origin as mValidRegion.GetBounds(). * Any tile that does not intersect mValidRegion is a PlaceholderTile. * Only the region intersecting with mValidRegion should be read from a tile, - * another other region is assumed to be uninitialized. + * another other region is assumed to be uninitialized. The contents of the + * tiles is scaled by mResolution. */ nsTArray mRetainedTiles; int mRetainedWidth; // in tiles int mRetainedHeight; // in tiles + float mResolution; private: const Derived& AsDerived() const { return *static_cast(this); } @@ -187,10 +216,10 @@ TiledLayerBuffer::GetTile(const nsIntPoint& aTileOrigin) const // TODO Cache firstTileOriginX/firstTileOriginY // Find the tile x/y of the first tile and the target tile relative to the (0, 0) // origin, the difference is the tile x/y relative to the start of the tile buffer. - int firstTileX = floor_div(mValidRegion.GetBounds().x, GetTileLength()); - int firstTileY = floor_div(mValidRegion.GetBounds().y, GetTileLength()); - return GetTile(floor_div(aTileOrigin.x, GetTileLength()) - firstTileX, - floor_div(aTileOrigin.y, GetTileLength()) - firstTileY); + int firstTileX = floor_div(mValidRegion.GetBounds().x, GetScaledTileLength()); + int firstTileY = floor_div(mValidRegion.GetBounds().y, GetScaledTileLength()); + return GetTile(floor_div(aTileOrigin.x, GetScaledTileLength()) - firstTileX, + floor_div(aTileOrigin.y, GetScaledTileLength()) - firstTileY); } template Tile @@ -204,10 +233,10 @@ template bool TiledLayerBuffer::RemoveTile(const nsIntPoint& aTileOrigin, Tile& aRemovedTile) { - int firstTileX = floor_div(mValidRegion.GetBounds().x, GetTileLength()); - int firstTileY = floor_div(mValidRegion.GetBounds().y, GetTileLength()); - return RemoveTile(floor_div(aTileOrigin.x, GetTileLength()) - firstTileX, - floor_div(aTileOrigin.y, GetTileLength()) - firstTileY, + int firstTileX = floor_div(mValidRegion.GetBounds().x, GetScaledTileLength()); + int firstTileY = floor_div(mValidRegion.GetBounds().y, GetScaledTileLength()); + return RemoveTile(floor_div(aTileOrigin.x, GetScaledTileLength()) - firstTileX, + floor_div(aTileOrigin.y, GetScaledTileLength()) - firstTileY, aRemovedTile); } @@ -251,14 +280,14 @@ TiledLayerBuffer::Update(const nsIntRegion& aNewValidRegion, for (int32_t x = newBound.x; x < newBound.XMost(); tileX++) { // Compute tileRect(x,y,width,height) in layer space coordinate // giving us the rect of the tile that hits the newBounds. - int width = GetTileLength() - GetTileStart(x); + int width = GetScaledTileLength() - GetTileStart(x); if (x + width > newBound.XMost()) { width = newBound.x + newBound.width - x; } tileY = 0; for (int32_t y = newBound.y; y < newBound.YMost(); tileY++) { - int height = GetTileLength() - GetTileStart(y); + int height = GetScaledTileLength() - GetTileStart(y); if (y + height > newBound.y + newBound.height) { height = newBound.y + newBound.height - y; } @@ -268,8 +297,8 @@ TiledLayerBuffer::Update(const nsIntRegion& aNewValidRegion, // This old tiles contains some valid area so move it to the new tile // buffer. Replace the tile in the old buffer with a placeholder // to leave the old buffer index unaffected. - int tileX = floor_div(x - oldBufferOrigin.x, GetTileLength()); - int tileY = floor_div(y - oldBufferOrigin.y, GetTileLength()); + int tileX = floor_div(x - oldBufferOrigin.x, GetScaledTileLength()); + int tileY = floor_div(y - oldBufferOrigin.y, GetScaledTileLength()); int index = tileX * oldRetainedHeight + tileY; // The tile may have been removed, skip over it in this case. @@ -328,14 +357,14 @@ TiledLayerBuffer::Update(const nsIntRegion& aNewValidRegion, // Compute tileRect(x,y,width,height) in layer space coordinate // giving us the rect of the tile that hits the newBounds. int tileStartX = RoundDownToTileEdge(x); - int width = GetTileLength() - GetTileStart(x); + int width = GetScaledTileLength() - GetTileStart(x); if (x + width > newBound.XMost()) width = newBound.XMost() - x; tileY = 0; for (int y = newBound.y; y < newBound.y + newBound.height; tileY++) { int tileStartY = RoundDownToTileEdge(y); - int height = GetTileLength() - GetTileStart(y); + int height = GetScaledTileLength() - GetTileStart(y); if (y + height > newBound.YMost()) { height = newBound.YMost() - y; } @@ -350,8 +379,8 @@ TiledLayerBuffer::Update(const nsIntRegion& aNewValidRegion, // because we can reuse all of the content from the // previous buffer. #ifdef DEBUG - int currTileX = floor_div(x - newBufferOrigin.x, GetTileLength()); - int currTileY = floor_div(y - newBufferOrigin.y, GetTileLength()); + int currTileX = floor_div(x - newBufferOrigin.x, GetScaledTileLength()); + int currTileY = floor_div(y - newBufferOrigin.y, GetScaledTileLength()); int index = currTileX * mRetainedHeight + currTileY; NS_ABORT_IF_FALSE(!newValidRegion.Intersects(tileRect) || !IsPlaceholder(newRetainedTiles. @@ -362,8 +391,8 @@ TiledLayerBuffer::Update(const nsIntRegion& aNewValidRegion, continue; } - int tileX = floor_div(x - newBufferOrigin.x, GetTileLength()); - int tileY = floor_div(y - newBufferOrigin.y, GetTileLength()); + int tileX = floor_div(x - newBufferOrigin.x, GetScaledTileLength()); + int tileY = floor_div(y - newBufferOrigin.y, GetScaledTileLength()); int index = tileX * mRetainedHeight + tileY; NS_ABORT_IF_FALSE(index >= 0 && static_cast(index) < newRetainedTiles.Length(), diff --git a/gfx/layers/basic/BasicTiledThebesLayer.cpp b/gfx/layers/basic/BasicTiledThebesLayer.cpp index 94de90961c5d..a259790f67ac 100644 --- a/gfx/layers/basic/BasicTiledThebesLayer.cpp +++ b/gfx/layers/basic/BasicTiledThebesLayer.cpp @@ -105,11 +105,15 @@ BasicTiledLayerBuffer::PaintThebes(BasicTiledThebesLayer* aLayer, const nsIntRect bounds = aPaintRegion.GetBounds(); { SAMPLE_LABEL("BasicTiledLayerBuffer", "PaintThebesSingleBufferAlloc"); - mSinglePaintBuffer = new gfxImageSurface(gfxIntSize(bounds.width, bounds.height), GetFormat(), !aLayer->CanUseOpaqueSurface()); + mSinglePaintBuffer = new gfxImageSurface( + gfxIntSize(ceilf(bounds.width * mResolution), + ceilf(bounds.height * mResolution)), + GetFormat(), !aLayer->CanUseOpaqueSurface()); mSinglePaintBufferOffset = nsIntPoint(bounds.x, bounds.y); } nsRefPtr ctxt = new gfxContext(mSinglePaintBuffer); ctxt->NewPath(); + ctxt->Scale(mResolution, mResolution); ctxt->Translate(gfxPoint(-bounds.x, -bounds.y)); #ifdef GFX_TILEDLAYER_PREF_WARNINGS if (PR_IntervalNow() - start > 3) { @@ -165,9 +169,6 @@ BasicTiledLayerBuffer::ValidateTileInternal(BasicTiledLayerTile aTile, aTile = BasicTiledLayerTile(tmpTile); } - gfxRect drawRect(aDirtyRect.x - aTileOrigin.x, aDirtyRect.y - aTileOrigin.y, - aDirtyRect.width, aDirtyRect.height); - // Use the gfxReusableSurfaceWrapper, which will reuse the surface // if the compositor no longer has a read lock, otherwise the surface // will be copied into a new writable surface. @@ -176,23 +177,35 @@ BasicTiledLayerBuffer::ValidateTileInternal(BasicTiledLayerTile aTile, // Bug 742100, this gfxContext really should live on the stack. nsRefPtr ctxt = new gfxContext(writableSurface); + if (mSinglePaintBuffer) { + gfxRect drawRect(aDirtyRect.x - aTileOrigin.x, aDirtyRect.y - aTileOrigin.y, + aDirtyRect.width, aDirtyRect.height); + ctxt->SetOperator(gfxContext::OPERATOR_SOURCE); ctxt->NewPath(); ctxt->SetSource(mSinglePaintBuffer.get(), - gfxPoint(mSinglePaintBufferOffset.x - aDirtyRect.x + drawRect.x, - mSinglePaintBufferOffset.y - aDirtyRect.y + drawRect.y)); + gfxPoint((mSinglePaintBufferOffset.x - aDirtyRect.x + drawRect.x) * + mResolution, + (mSinglePaintBufferOffset.y - aDirtyRect.y + drawRect.y) * + mResolution)); + drawRect.Scale(mResolution, mResolution); ctxt->Rectangle(drawRect, true); ctxt->Fill(); } else { ctxt->NewPath(); + ctxt->Scale(mResolution, mResolution); ctxt->Translate(gfxPoint(-aTileOrigin.x, -aTileOrigin.y)); - nsIntPoint a = aTileOrigin; - mCallback(mThebesLayer, ctxt, nsIntRegion(nsIntRect(a, nsIntSize(GetTileLength(), GetTileLength()))), nsIntRegion(), mCallbackData); + nsIntPoint a = nsIntPoint(aTileOrigin.x, aTileOrigin.y); + mCallback(mThebesLayer, ctxt, + nsIntRegion(nsIntRect(a, nsIntSize(GetScaledTileLength(), + GetScaledTileLength()))), + nsIntRegion(), mCallbackData); } #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY - DrawDebugOverlay(writableSurface, aTileOrigin.x, aTileOrigin.y); + DrawDebugOverlay(writableSurface, aTileOrigin.x * mResolution, + aTileOrigin.y * mResolution); #endif return aTile; @@ -303,26 +316,25 @@ BasicTiledThebesLayer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInvali nsIntRect paintBounds = aRegionToPaint.GetBounds(); int startX, incX, startY, incY; + int tileLength = mTiledBuffer.GetScaledTileLength(); if (aScrollOffset.x >= mLastScrollOffset.x) { startX = mTiledBuffer.RoundDownToTileEdge(paintBounds.x); - incX = mTiledBuffer.GetTileLength(); + incX = tileLength; } else { startX = mTiledBuffer.RoundDownToTileEdge(paintBounds.XMost() - 1); - incX = -mTiledBuffer.GetTileLength(); + incX = -tileLength; } if (aScrollOffset.y >= mLastScrollOffset.y) { startY = mTiledBuffer.RoundDownToTileEdge(paintBounds.y); - incY = mTiledBuffer.GetTileLength(); + incY = tileLength; } else { startY = mTiledBuffer.RoundDownToTileEdge(paintBounds.YMost() - 1); - incY = -mTiledBuffer.GetTileLength(); + incY = -tileLength; } // Find a tile to draw. - nsIntRect tileBounds(startX, startY, - mTiledBuffer.GetTileLength(), - mTiledBuffer.GetTileLength()); + nsIntRect tileBounds(startX, startY, tileLength, tileLength); int32_t scrollDiffX = aScrollOffset.x - mLastScrollOffset.x; int32_t scrollDiffY = aScrollOffset.y - mLastScrollOffset.y; // This loop will always terminate, as there is at least one tile area @@ -429,7 +441,7 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext, // Only draw progressively when the resolution is unchanged. if (gfxPlatform::UseProgressiveTilePainting() && !BasicManager()->HasShadowTarget() && - mTiledBuffer.GetResolution() == resolution) { + mTiledBuffer.GetFrameResolution() == resolution) { // Store the old valid region, then clear it before painting. // We clip the old valid region to the visible region, as it only gets // used to decide stale content (currently valid and previously visible) @@ -495,7 +507,7 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext, } while (repeat); } else { mTiledBuffer.ClearPaintedRegion(); - mTiledBuffer.SetResolution(resolution); + mTiledBuffer.SetFrameResolution(resolution); mValidRegion = mVisibleRegion; if (!layerDisplayPort.IsEmpty()) { mValidRegion.And(mValidRegion, layerDisplayPort); diff --git a/gfx/layers/basic/BasicTiledThebesLayer.h b/gfx/layers/basic/BasicTiledThebesLayer.h index b035e198538b..dbcb96ba7713 100644 --- a/gfx/layers/basic/BasicTiledThebesLayer.h +++ b/gfx/layers/basic/BasicTiledThebesLayer.h @@ -107,8 +107,8 @@ public: } } - const gfxSize& GetResolution() { return mResolution; } - void SetResolution(const gfxSize& aResolution) { mResolution = aResolution; } + const gfxSize& GetFrameResolution() { return mFrameResolution; } + void SetFrameResolution(const gfxSize& aResolution) { mFrameResolution = aResolution; } bool HasFormatChanged(BasicTiledThebesLayer* aThebesLayer) const; protected: @@ -133,7 +133,7 @@ private: BasicTiledThebesLayer* mThebesLayer; LayerManager::DrawThebesLayerCallback mCallback; void* mCallbackData; - gfxSize mResolution; + gfxSize mFrameResolution; bool mLastPaintOpaque; // The buffer we use when UseSinglePaintBuffer() above is true. diff --git a/gfx/layers/opengl/ReusableTileStoreOGL.cpp b/gfx/layers/opengl/ReusableTileStoreOGL.cpp index d06ffc52e828..63e4d531785e 100644 --- a/gfx/layers/opengl/ReusableTileStoreOGL.cpp +++ b/gfx/layers/opengl/ReusableTileStoreOGL.cpp @@ -136,6 +136,9 @@ ReusableTileStoreOGL::HarvestTiles(TiledThebesLayerOGL* aLayer, const gfxSize& aOldResolution, const gfxSize& aNewResolution) { + NS_ASSERTION(aVideoMemoryTiledBuffer->GetResolution() == 1.0f, + "ReusableTileStoreOGL cannot harvest scaled tiles!"); + gfxSize scaleFactor = gfxSize(aNewResolution.width / aOldResolution.width, aNewResolution.height / aOldResolution.height); diff --git a/gfx/layers/opengl/TiledThebesLayerOGL.cpp b/gfx/layers/opengl/TiledThebesLayerOGL.cpp index 9d797285b181..4013b5fb15cd 100644 --- a/gfx/layers/opengl/TiledThebesLayerOGL.cpp +++ b/gfx/layers/opengl/TiledThebesLayerOGL.cpp @@ -46,7 +46,7 @@ TiledLayerBufferOGL::Upload(const BasicTiledLayerBuffer* aMainMemoryTiledBuffer, long start = PR_IntervalNow(); #endif - mResolution = aResolution; + mFrameResolution = aResolution; mMainMemoryTiledBuffer = aMainMemoryTiledBuffer; mContext->MakeCurrent(); Update(aNewValidRegion, aInvalidateRegion); @@ -181,7 +181,7 @@ TiledThebesLayerOGL::ProcessUploadQueue() &mVideoMemoryTiledBuffer, mVideoMemoryTiledBuffer.GetValidRegion(), mMainMemoryTiledBuffer.GetValidRegion(), - mVideoMemoryTiledBuffer.GetResolution(), + mVideoMemoryTiledBuffer.GetFrameResolution(), resolution); } @@ -192,6 +192,7 @@ TiledThebesLayerOGL::ProcessUploadQueue() mVideoMemoryTiledBuffer.Upload(&mMainMemoryTiledBuffer, mMainMemoryTiledBuffer.GetValidRegion(), mRegionToUpload, resolution); + mVideoMemoryTiledBuffer.SetResolution(mMainMemoryTiledBuffer.GetResolution()); mValidRegion = mVideoMemoryTiledBuffer.GetValidRegion(); mMainMemoryTiledBuffer.ReadUnlock(); @@ -252,26 +253,29 @@ TiledThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOf if (mReusableTileStore) { mReusableTileStore->DrawTiles(this, mVideoMemoryTiledBuffer.GetValidRegion(), - mVideoMemoryTiledBuffer.GetResolution(), + mVideoMemoryTiledBuffer.GetFrameResolution(), GetEffectiveTransform(), aOffset, maskLayer); } // Render valid tiles. const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion(); const nsIntRect visibleRect = visibleRegion.GetBounds(); + float resolution = mVideoMemoryTiledBuffer.GetResolution(); + gfx3DMatrix transform = GetEffectiveTransform(); + transform.Scale(1/resolution, 1/resolution, 1); uint32_t rowCount = 0; uint32_t tileX = 0; for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { rowCount++; int32_t tileStartX = mVideoMemoryTiledBuffer.GetTileStart(x); - int16_t w = mVideoMemoryTiledBuffer.GetTileLength() - tileStartX; + int32_t w = mVideoMemoryTiledBuffer.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); - int16_t h = mVideoMemoryTiledBuffer.GetTileLength() - tileStartY; + int32_t h = mVideoMemoryTiledBuffer.GetScaledTileLength() - tileStartY; if (y + h > visibleRect.y + visibleRect.height) h = visibleRect.y + visibleRect.height - y; @@ -281,10 +285,12 @@ TiledThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOf if (tileTexture != mVideoMemoryTiledBuffer.GetPlaceholderTile()) { nsIntRegion tileDrawRegion = nsIntRegion(nsIntRect(x, y, w, h)); tileDrawRegion.And(tileDrawRegion, mValidRegion); + tileDrawRegion.ScaleRoundOut(resolution, resolution); - nsIntPoint tileOffset(x - tileStartX, y - tileStartY); - uint16_t tileSize = mVideoMemoryTiledBuffer.GetTileLength(); - RenderTile(tileTexture, GetEffectiveTransform(), aOffset, tileDrawRegion, + nsIntPoint tileOffset((x - tileStartX) * resolution, + (y - tileStartY) * resolution); + uint32_t tileSize = mVideoMemoryTiledBuffer.GetTileLength(); + RenderTile(tileTexture, transform, aOffset, tileDrawRegion, tileOffset, nsIntSize(tileSize, tileSize), maskLayer); } tileY++; diff --git a/gfx/layers/opengl/TiledThebesLayerOGL.h b/gfx/layers/opengl/TiledThebesLayerOGL.h index 494b652cf864..9a15d76357b1 100644 --- a/gfx/layers/opengl/TiledThebesLayerOGL.h +++ b/gfx/layers/opengl/TiledThebesLayerOGL.h @@ -80,7 +80,9 @@ public: TiledTexture GetPlaceholderTile() const { return TiledTexture(); } - const gfxSize& GetResolution() { return mResolution; } + // Stores the absolute resolution of the containing frame, calculated + // by the sum of the resolutions of all parent layers' FrameMetrics. + const gfxSize& GetFrameResolution() { return mFrameResolution; } protected: TiledTexture ValidateTile(TiledTexture aTile, @@ -96,7 +98,7 @@ protected: private: nsRefPtr mContext; const BasicTiledLayerBuffer* mMainMemoryTiledBuffer; - gfxSize mResolution; + gfxSize mFrameResolution; void GetFormatAndTileForImageFormat(gfxASurface::gfxImageFormat aFormat, GLenum& aOutFormat,