зеркало из https://github.com/mozilla/pjs.git
Bug 607687 - Fennec should take care about Texture MAX size HW limitation r=jmuizelaar
This commit is contained in:
Родитель
b7858d4918
Коммит
de4075b859
|
@ -366,19 +366,21 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||
{
|
||||
mOGLManager->MakeCurrent();
|
||||
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexImage->Texture());
|
||||
ColorTextureLayerProgram *program =
|
||||
mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
|
||||
|
||||
ApplyFilter(mFilter);
|
||||
|
||||
program->Activate();
|
||||
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mTexImage->GetSize()));
|
||||
program->SetLayerTransform(GetEffectiveTransform());
|
||||
program->SetLayerOpacity(GetEffectiveOpacity());
|
||||
program->SetRenderOffset(aOffset);
|
||||
program->SetTextureUnit(0);
|
||||
|
||||
mOGLManager->BindAndDrawQuad(program, mNeedsYFlip ? true : false);
|
||||
mTexImage->BeginTileIteration();
|
||||
do {
|
||||
TextureImage::ScopedBindTexture texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
program->SetLayerQuadRect(mTexImage->GetTileRect());
|
||||
mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles?
|
||||
} while (mTexImage->NextTile());
|
||||
}
|
||||
|
|
|
@ -938,20 +938,20 @@ ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||
{
|
||||
mOGLManager->MakeCurrent();
|
||||
|
||||
LayerProgram* program;
|
||||
|
||||
if (mTexImage) {
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexImage->Texture());
|
||||
ColorTextureLayerProgram *colorProgram =
|
||||
mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
|
||||
|
||||
ApplyFilter(mFilter);
|
||||
|
||||
colorProgram->Activate();
|
||||
colorProgram->SetTextureUnit(0);
|
||||
colorProgram->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mTexImage->GetSize()));
|
||||
program = colorProgram;
|
||||
|
||||
mTexImage->BeginTileIteration();
|
||||
do {
|
||||
TextureImage::ScopedBindTexture texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
ApplyFilter(mFilter);
|
||||
colorProgram->SetLayerQuadRect(mTexImage->GetTileRect());
|
||||
mOGLManager->BindAndDrawQuad(colorProgram);
|
||||
} while (mTexImage->NextTile());
|
||||
} else {
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[0].GetTextureID());
|
||||
|
@ -970,24 +970,14 @@ ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||
mPictureRect.width,
|
||||
mPictureRect.height));
|
||||
yuvProgram->SetYCbCrTextureUnits(0, 1, 2);
|
||||
yuvProgram->SetLayerTransform(GetEffectiveTransform());
|
||||
yuvProgram->SetLayerOpacity(GetEffectiveOpacity());
|
||||
yuvProgram->SetRenderOffset(aOffset);
|
||||
|
||||
program = yuvProgram;
|
||||
program->SetLayerTransform(GetEffectiveTransform());
|
||||
program->SetLayerOpacity(GetEffectiveOpacity());
|
||||
program->SetRenderOffset(aOffset);
|
||||
|
||||
mOGLManager->BindAndDrawQuadWithTextureRect(program,
|
||||
mOGLManager->BindAndDrawQuadWithTextureRect(yuvProgram,
|
||||
mPictureRect,
|
||||
nsIntSize(mSize.width, mSize.height));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
program->SetLayerTransform(GetEffectiveTransform());
|
||||
program->SetLayerOpacity(GetEffectiveOpacity());
|
||||
program->SetRenderOffset(aOffset);
|
||||
|
||||
mOGLManager->BindAndDrawQuad(program);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -141,10 +141,6 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
|
|||
mTexImageOnWhite->EndUpdate();
|
||||
}
|
||||
|
||||
// Bind textures.
|
||||
TextureImage::ScopedBindTexture texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
TextureImage::ScopedBindTexture texOnWhiteBind(mTexImageOnWhite, LOCAL_GL_TEXTURE1);
|
||||
|
||||
PRInt32 passes = mTexImageOnWhite ? 2 : 1;
|
||||
for (PRInt32 pass = 1; pass <= passes; ++pass) {
|
||||
LayerProgram *program;
|
||||
|
@ -194,17 +190,42 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
|
|||
} else {
|
||||
renderRegion = &visibleRegion;
|
||||
}
|
||||
nsIntRegionRectIterator iter(*renderRegion);
|
||||
|
||||
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)
|
||||
|
||||
do {
|
||||
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;
|
||||
}
|
||||
// Bind textures.
|
||||
TextureImage::ScopedBindTexture texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
TextureImage::ScopedBindTexture texOnWhiteBind(mTexImageOnWhite, LOCAL_GL_TEXTURE1);
|
||||
|
||||
nsIntRegionRectIterator iter(subregion);
|
||||
while (const nsIntRect *iterRect = iter.Next()) {
|
||||
nsIntRect quadRect = *iterRect;
|
||||
program->SetLayerQuadRect(quadRect);
|
||||
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);
|
||||
|
||||
quadRect.MoveBy(-GetOriginOffset());
|
||||
|
||||
aManager->BindAndDrawQuadWithTextureRect(program, quadRect,
|
||||
mTexImage->GetSize(),
|
||||
regionRect.MoveBy(-mTexImage->GetTileRect().TopLeft()); // get region of tile
|
||||
aManager->BindAndDrawQuadWithTextureRect(program, regionRect,
|
||||
textureRect.Size(),
|
||||
mTexImage->GetWrapMode());
|
||||
}
|
||||
} while (mTexImage->NextTile());
|
||||
}
|
||||
|
||||
if (mTexImageOnWhite) {
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "GLContextProvider.h"
|
||||
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
#include "gfxUtils.h"
|
||||
|
||||
#include "mozilla/Util.h" // for DebugOnly
|
||||
|
||||
|
@ -636,7 +637,7 @@ void
|
|||
BasicTextureImage::BindTexture(GLenum aTextureUnit)
|
||||
{
|
||||
mGLContext->fActiveTexture(aTextureUnit);
|
||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, Texture());
|
||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
}
|
||||
|
||||
|
@ -659,7 +660,7 @@ BasicTextureImage::FinishedSurfaceUpload()
|
|||
}
|
||||
|
||||
bool
|
||||
BasicTextureImage::DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion)
|
||||
BasicTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */)
|
||||
{
|
||||
nsIntRect bounds = aRegion.GetBounds();
|
||||
nsIntRegion region;
|
||||
|
@ -675,7 +676,7 @@ BasicTextureImage::DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion)
|
|||
region,
|
||||
mTexture,
|
||||
mTextureState == Created,
|
||||
bounds.TopLeft(),
|
||||
bounds.TopLeft() + aFrom,
|
||||
PR_FALSE);
|
||||
mTextureState = Valid;
|
||||
return true;
|
||||
|
@ -702,6 +703,202 @@ BasicTextureImage::Resize(const nsIntSize& aSize)
|
|||
mSize = aSize;
|
||||
}
|
||||
|
||||
TiledTextureImage::TiledTextureImage(GLContext* aGL,
|
||||
nsIntSize aSize,
|
||||
TextureImage::ContentType aContentType,
|
||||
PRBool aUseNearestFilter)
|
||||
: TextureImage(aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, aUseNearestFilter)
|
||||
, mCurrentImage(0)
|
||||
, mInUpdate(PR_FALSE)
|
||||
, mGL(aGL)
|
||||
, mUseNearestFilter(aUseNearestFilter)
|
||||
, mTextureState(Created)
|
||||
{
|
||||
mTileSize = mGL->GetMaxTextureSize();
|
||||
if (aSize != nsIntSize(0,0)) {
|
||||
Resize(aSize);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
bounds = nsIntRect(0, 0, mSize.width, mSize.height);
|
||||
region = nsIntRegion(bounds);
|
||||
} else {
|
||||
region = aRegion;
|
||||
}
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
for (unsigned i = 0; i < mImages.Length(); i++) {
|
||||
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())
|
||||
continue;
|
||||
tileRegion.MoveBy(-xPos, -yPos); // translate into tile local space
|
||||
result &= mImages[i]->DirectUpdate(aSurf,
|
||||
tileRegion,
|
||||
aFrom + nsIntPoint(xPos, yPos));
|
||||
}
|
||||
mShaderType = mImages[0]->GetShaderProgramType();
|
||||
mIsRGBFormat = mImages[0]->IsRGB();
|
||||
mTextureState = Valid;
|
||||
return result;
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(!mInUpdate, "nested update");
|
||||
mInUpdate = PR_TRUE;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < mImages.Length(); i++) {
|
||||
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
|
||||
if (imageRegion.Contains(aRegion)) {
|
||||
// adjust for tile offset
|
||||
aRegion.MoveBy(-xPos, -yPos);
|
||||
// forward the actual call
|
||||
nsRefPtr<gfxASurface> surface = mImages[i]->BeginUpdate(aRegion);
|
||||
// caller expects container space
|
||||
aRegion.MoveBy(xPos, yPos);
|
||||
// we don't have a temp surface
|
||||
mUpdateSurface = nsnull;
|
||||
// remember which image to EndUpdate
|
||||
mCurrentImage = i;
|
||||
return surface.get();
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
void
|
||||
TiledTextureImage::EndUpdate()
|
||||
{
|
||||
NS_ASSERTION(mInUpdate, "EndUpdate not in update");
|
||||
if (!mUpdateSurface) { // update was to a single TextureImage
|
||||
mImages[mCurrentImage]->EndUpdate();
|
||||
mInUpdate = PR_FALSE;
|
||||
mTextureState = Valid;
|
||||
mShaderType = mImages[mCurrentImage]->GetShaderProgramType();
|
||||
mIsRGBFormat = mImages[mCurrentImage]->IsRGB();
|
||||
return;
|
||||
}
|
||||
|
||||
// upload tiles from temp surface
|
||||
for (unsigned i = 0; i < mImages.Length(); i++) {
|
||||
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())
|
||||
continue;
|
||||
subregion.MoveBy(-xPos, -yPos); // Tile-local space
|
||||
// copy tile from temp surface
|
||||
gfxASurface* surf = mImages[i]->BeginUpdate(subregion);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||
gfxUtils::ClipToRegion(ctx, subregion);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(mUpdateSurface, gfxPoint(-xPos, -yPos));
|
||||
ctx->Paint();
|
||||
mImages[i]->EndUpdate();
|
||||
}
|
||||
|
||||
mUpdateSurface = nsnull;
|
||||
mInUpdate = PR_FALSE;
|
||||
mShaderType = mImages[0]->GetShaderProgramType();
|
||||
mIsRGBFormat = mImages[0]->IsRGB();
|
||||
}
|
||||
|
||||
void TiledTextureImage::BeginTileIteration()
|
||||
{
|
||||
mCurrentImage = 0;
|
||||
}
|
||||
|
||||
PRBool TiledTextureImage::NextTile()
|
||||
{
|
||||
if (mCurrentImage + 1 < mImages.Length()) {
|
||||
mCurrentImage++;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIntRect TiledTextureImage::GetTileRect()
|
||||
{
|
||||
nsIntRect rect = mImages[mCurrentImage]->GetTileRect();
|
||||
unsigned int xPos = (mCurrentImage % mColumns) * mTileSize;
|
||||
unsigned int yPos = (mCurrentImage / mColumns) * mTileSize;
|
||||
rect.MoveTo(xPos, yPos);
|
||||
return rect;
|
||||
}
|
||||
|
||||
void
|
||||
TiledTextureImage::BindTexture(GLenum aTextureUnit)
|
||||
{
|
||||
mImages[mCurrentImage]->BindTexture(aTextureUnit);
|
||||
}
|
||||
|
||||
/*
|
||||
* simple resize, just discards everything. we can be more clever just
|
||||
* adding or discarding tiles, but do we want this?
|
||||
*/
|
||||
void TiledTextureImage::Resize(const nsIntSize& aSize)
|
||||
{
|
||||
if (mSize == aSize && mTextureState != Created) {
|
||||
return;
|
||||
}
|
||||
mSize = aSize;
|
||||
mImages.Clear();
|
||||
// calculate rows and columns, rounding up
|
||||
mColumns = (aSize.width + mTileSize - 1) / mTileSize;
|
||||
mRows = (aSize.height + mTileSize - 1) / mTileSize;
|
||||
|
||||
for (unsigned int row = 0; row < mRows; row++) {
|
||||
for (unsigned int col = 0; col < mColumns; col++) {
|
||||
nsIntSize size( // use tilesize first, then the remainder
|
||||
(col+1) * mTileSize > (unsigned int)aSize.width ? aSize.width % mTileSize : mTileSize,
|
||||
(row+1) * mTileSize > (unsigned int)aSize.height ? aSize.height % mTileSize : mTileSize);
|
||||
nsRefPtr<TextureImage> teximg =
|
||||
mGL->TileGenFunc(size, mContentType, mUseNearestFilter);
|
||||
mImages.AppendElement(teximg.forget());
|
||||
}
|
||||
}
|
||||
mTextureState = Allocated;
|
||||
}
|
||||
|
||||
PRBool
|
||||
GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
|
||||
{
|
||||
|
@ -1245,6 +1442,9 @@ GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
|
|||
NS_ASSERTION(!aSrc->InUpdate(), "Source texture is in update!");
|
||||
NS_ASSERTION(!aDst->InUpdate(), "Destination texture is in update!");
|
||||
|
||||
if (aSrcRect.IsEmpty() || aDstRect.IsEmpty())
|
||||
return;
|
||||
|
||||
// only save/restore this stuff on Qualcomm Adreno, to work
|
||||
// around an apparent bug
|
||||
int savedFb = 0;
|
||||
|
@ -1255,44 +1455,97 @@ GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
|
|||
fDisable(LOCAL_GL_SCISSOR_TEST);
|
||||
fDisable(LOCAL_GL_BLEND);
|
||||
|
||||
SetBlitFramebufferForDestTexture(aDst->Texture());
|
||||
// 2.0 means scale up by two
|
||||
float blitScaleX = float(aDstRect.width) / float(aSrcRect.width);
|
||||
float blitScaleY = float(aDstRect.height) / float(aSrcRect.height);
|
||||
|
||||
// We start iterating over all destination tiles
|
||||
aDst->BeginTileIteration();
|
||||
do {
|
||||
// calculate portion of the tile that is going to be painted to
|
||||
nsIntRect dstSubRect;
|
||||
nsIntRect dstTextureRect = aDst->GetTileRect();
|
||||
dstSubRect.IntersectRect(aDstRect, dstTextureRect);
|
||||
|
||||
// this tile is not part of the destination rectangle aDstRect
|
||||
if (dstSubRect.IsEmpty())
|
||||
continue;
|
||||
|
||||
// (*) transform the rect of this tile into the rectangle defined by aSrcRect...
|
||||
nsIntRect dstInSrcRect(dstSubRect);
|
||||
dstInSrcRect.MoveBy(-aDstRect.TopLeft());
|
||||
// ...which might be of different size, hence scale accordingly
|
||||
dstInSrcRect.ScaleRoundOut(1.0f / blitScaleX, 1.0f / blitScaleY);
|
||||
dstInSrcRect.MoveBy(aSrcRect.TopLeft());
|
||||
|
||||
SetBlitFramebufferForDestTexture(aDst->GetTextureID());
|
||||
UseBlitProgram();
|
||||
|
||||
nsIntSize srcSize = aSrc->GetSize();
|
||||
nsIntSize dstSize = aDst->GetSize();
|
||||
aSrc->BeginTileIteration();
|
||||
// now iterate over all tiles in the source Image...
|
||||
do {
|
||||
// calculate portion of the source tile that is in the source rect
|
||||
nsIntRect srcSubRect;
|
||||
nsIntRect srcTextureRect = aSrc->GetTileRect();
|
||||
srcSubRect.IntersectRect(aSrcRect, srcTextureRect);
|
||||
|
||||
// this tile is not part of the source rect
|
||||
if (srcSubRect.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
// calculate intersection of source rect with destination rect
|
||||
srcSubRect.IntersectRect(srcSubRect, dstInSrcRect);
|
||||
// this tile does not overlap the current destination tile
|
||||
if (srcSubRect.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
// We now have the intersection of
|
||||
// the current source tile
|
||||
// and the desired source rectangle
|
||||
// and the destination tile
|
||||
// and the desired destination rectange
|
||||
// in destination space.
|
||||
// We need to transform this back into destination space, inverting the transform from (*)
|
||||
nsIntRect srcSubInDstRect(srcSubRect);
|
||||
srcSubInDstRect.MoveBy(-aSrcRect.TopLeft());
|
||||
srcSubInDstRect.ScaleRoundOut(blitScaleX, blitScaleY);
|
||||
srcSubInDstRect.MoveBy(aDstRect.TopLeft());
|
||||
|
||||
// we transform these rectangles to be relative to the current src and dst tiles, respectively
|
||||
nsIntSize srcSize = srcTextureRect.Size();
|
||||
nsIntSize dstSize = dstTextureRect.Size();
|
||||
srcSubRect.MoveBy(-srcTextureRect.x, -srcTextureRect.y);
|
||||
srcSubInDstRect.MoveBy(-dstTextureRect.x, -dstTextureRect.y);
|
||||
|
||||
float dx0 = 2.0 * float(srcSubInDstRect.x) / float(dstSize.width) - 1.0;
|
||||
float dy0 = 2.0 * float(srcSubInDstRect.y) / float(dstSize.height) - 1.0;
|
||||
float dx1 = 2.0 * float(srcSubInDstRect.x + srcSubInDstRect.width) / float(dstSize.width) - 1.0;
|
||||
float dy1 = 2.0 * float(srcSubInDstRect.y + srcSubInDstRect.height) / float(dstSize.height) - 1.0;
|
||||
PushViewportRect(nsIntRect(0, 0, dstSize.width, dstSize.height));
|
||||
|
||||
float dx0 = 2.0 * float(aDstRect.x) / float(dstSize.width) - 1.0;
|
||||
float dy0 = 2.0 * float(aDstRect.y) / float(dstSize.height) - 1.0;
|
||||
float dx1 = 2.0 * float(aDstRect.x + aDstRect.width) / float(dstSize.width) - 1.0;
|
||||
float dy1 = 2.0 * float(aDstRect.y + aDstRect.height) / float(dstSize.height) - 1.0;
|
||||
|
||||
RectTriangles rects;
|
||||
if (aSrc->GetWrapMode() == LOCAL_GL_REPEAT) {
|
||||
rects.addRect(/* dest rectangle */
|
||||
dx0, dy0, dx1, dy1,
|
||||
/* tex coords */
|
||||
aSrcRect.x / float(srcSize.width),
|
||||
aSrcRect.y / float(srcSize.height),
|
||||
aSrcRect.XMost() / float(srcSize.width),
|
||||
aSrcRect.YMost() / float(srcSize.height));
|
||||
srcSubRect.x / float(srcSize.width),
|
||||
srcSubRect.y / float(srcSize.height),
|
||||
srcSubRect.XMost() / float(srcSize.width),
|
||||
srcSubRect.YMost() / float(srcSize.height));
|
||||
} else {
|
||||
DecomposeIntoNoRepeatTriangles(aSrcRect, srcSize, rects);
|
||||
DecomposeIntoNoRepeatTriangles(srcSubRect, srcSize, rects);
|
||||
|
||||
// now put the coords into the d[xy]0 .. d[xy]1 coordinate space
|
||||
// from the 0..1 that it comes out of decompose
|
||||
RectTriangles::vert_coord* v = (RectTriangles::vert_coord*)rects.vertexPointer();
|
||||
for (int i = 0; i < rects.elements(); ++i) {
|
||||
|
||||
for (unsigned int i = 0; i < rects.elements(); ++i) {
|
||||
v[i].x = (v[i].x * (dx1 - dx0)) + dx0;
|
||||
v[i].y = (v[i].y * (dy1 - dy0)) + dy0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
fBindTexture(LOCAL_GL_TEXTURE_2D, aSrc->Texture());
|
||||
TextureImage::ScopedBindTexture texBind(aSrc, LOCAL_GL_TEXTURE0);
|
||||
|
||||
fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||
|
||||
|
@ -1307,6 +1560,10 @@ GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
|
|||
fDisableVertexAttribArray(0);
|
||||
fDisableVertexAttribArray(1);
|
||||
|
||||
PopViewportRect();
|
||||
} while (aSrc->NextTile());
|
||||
} while (aDst->NextTile());
|
||||
|
||||
fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, NULL);
|
||||
fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, NULL);
|
||||
|
||||
|
@ -1325,8 +1582,6 @@ GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
|
|||
|
||||
fEnable(LOCAL_GL_SCISSOR_TEST);
|
||||
fEnable(LOCAL_GL_BLEND);
|
||||
|
||||
PopViewportRect();
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
|
|
@ -75,8 +75,12 @@ typedef char realGLboolean;
|
|||
#include "GLContextSymbols.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
namespace layers {
|
||||
class LayerManagerOGL;
|
||||
class ColorTextureLayerProgram;
|
||||
};
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
|
||||
class LibrarySymbolLoader
|
||||
|
@ -156,6 +160,13 @@ class TextureImage
|
|||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(TextureImage)
|
||||
public:
|
||||
enum TextureState
|
||||
{
|
||||
Created, // Texture created, but has not had glTexImage called to initialize it.
|
||||
Allocated, // Texture memory exists, but contents are invalid.
|
||||
Valid // Texture fully ready to use.
|
||||
};
|
||||
|
||||
typedef gfxASurface::gfxContentType ContentType;
|
||||
|
||||
virtual ~TextureImage() {}
|
||||
|
@ -191,6 +202,22 @@ public:
|
|||
*/
|
||||
virtual void EndUpdate() = 0;
|
||||
|
||||
/**
|
||||
* The Image may contain several textures for different regions (tiles).
|
||||
* These functions iterate over each sub texture image tile.
|
||||
*/
|
||||
virtual void BeginTileIteration() {
|
||||
};
|
||||
|
||||
virtual PRBool NextTile() {
|
||||
return PR_FALSE;
|
||||
};
|
||||
|
||||
virtual nsIntRect GetTileRect() {
|
||||
return nsIntRect(nsIntPoint(0,0), mSize);
|
||||
};
|
||||
|
||||
virtual GLuint GetTextureID() = 0;
|
||||
/**
|
||||
* Set this TextureImage's size, and ensure a texture has been
|
||||
* allocated. Must not be called between BeginUpdate and EndUpdate.
|
||||
|
@ -206,7 +233,12 @@ public:
|
|||
EndUpdate();
|
||||
}
|
||||
|
||||
virtual bool DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion) =0;
|
||||
/**
|
||||
* aSurf - the source surface to update from
|
||||
* aRegion - the region in this image to update
|
||||
* aFrom - offset in the source to update from
|
||||
*/
|
||||
virtual bool DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0)) = 0;
|
||||
|
||||
virtual void BindTexture(GLenum aTextureUnit) = 0;
|
||||
virtual void ReleaseTexture() {};
|
||||
|
@ -233,16 +265,6 @@ public:
|
|||
TextureImage *mTexture;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return this TextureImage's texture ID for use with GL APIs.
|
||||
* Callers are responsible for properly binding the texture etc.
|
||||
*
|
||||
* The texture is only texture complete after either Resize
|
||||
* or a matching pair of BeginUpdate/EndUpdate have been called.
|
||||
* Otherwise, a texture ID may be returned, but the texture
|
||||
* may not be texture complete.
|
||||
*/
|
||||
GLuint Texture() { return mTexture; }
|
||||
|
||||
/**
|
||||
* Returns the shader program type that should be used to render
|
||||
|
@ -279,17 +301,15 @@ protected:
|
|||
* TextureImage from GLContext::CreateTextureImage(). That is,
|
||||
* clients must not be given partially-constructed TextureImages.
|
||||
*/
|
||||
TextureImage(GLuint aTexture, const nsIntSize& aSize,
|
||||
TextureImage(const nsIntSize& aSize,
|
||||
GLenum aWrapMode, ContentType aContentType,
|
||||
PRBool aIsRGB = PR_FALSE)
|
||||
: mTexture(aTexture)
|
||||
, mSize(aSize)
|
||||
: mSize(aSize)
|
||||
, mWrapMode(aWrapMode)
|
||||
, mContentType(aContentType)
|
||||
, mIsRGBFormat(aIsRGB)
|
||||
{}
|
||||
|
||||
GLuint mTexture;
|
||||
nsIntSize mSize;
|
||||
GLenum mWrapMode;
|
||||
ContentType mContentType;
|
||||
|
@ -318,25 +338,19 @@ public:
|
|||
GLenum aWrapMode,
|
||||
ContentType aContentType,
|
||||
GLContext* aContext)
|
||||
: TextureImage(aTexture, aSize, aWrapMode, aContentType)
|
||||
: TextureImage(aSize, aWrapMode, aContentType)
|
||||
, mTexture(aTexture)
|
||||
, mTextureState(Created)
|
||||
, mGLContext(aContext)
|
||||
, mUpdateOffset(0, 0)
|
||||
{}
|
||||
|
||||
enum TextureState
|
||||
{
|
||||
Created, // Texture created, but has not had glTexImage called to initialize it.
|
||||
Allocated, // Texture memory exists, but contents are invalid.
|
||||
Valid // Texture fully ready to use.
|
||||
};
|
||||
|
||||
virtual void BindTexture(GLenum aTextureUnit);
|
||||
|
||||
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
|
||||
virtual void EndUpdate();
|
||||
virtual bool DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion);
|
||||
|
||||
virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
|
||||
virtual GLuint GetTextureID() { return mTexture; };
|
||||
// Returns a surface to draw into
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
|
||||
|
@ -354,6 +368,7 @@ public:
|
|||
virtual void Resize(const nsIntSize& aSize);
|
||||
protected:
|
||||
|
||||
GLuint mTexture;
|
||||
TextureState mTextureState;
|
||||
GLContext* mGLContext;
|
||||
nsRefPtr<gfxASurface> mUpdateSurface;
|
||||
|
@ -363,6 +378,47 @@ protected:
|
|||
nsIntPoint mUpdateOffset;
|
||||
};
|
||||
|
||||
/**
|
||||
* A container class that complements many sub TextureImages into a big TextureImage.
|
||||
* Aims to behave just like the real thing.
|
||||
*/
|
||||
|
||||
class TiledTextureImage
|
||||
: public TextureImage
|
||||
{
|
||||
public:
|
||||
TiledTextureImage(GLContext* aGL, nsIntSize aSize,
|
||||
TextureImage::ContentType aContentType, PRBool aUseNearestFilter = PR_FALSE);
|
||||
~TiledTextureImage();
|
||||
void DumpDiv();
|
||||
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
|
||||
virtual void EndUpdate();
|
||||
virtual void Resize(const nsIntSize& aSize);
|
||||
virtual void BeginTileIteration();
|
||||
virtual PRBool NextTile();
|
||||
virtual nsIntRect GetTileRect();
|
||||
virtual GLuint GetTextureID() {
|
||||
return mImages[mCurrentImage]->GetTextureID();
|
||||
};
|
||||
virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
|
||||
virtual PRBool InUpdate() const { return mInUpdate; };
|
||||
virtual void BindTexture(GLenum);
|
||||
protected:
|
||||
unsigned int mCurrentImage;
|
||||
nsTArray< nsRefPtr<TextureImage> > mImages;
|
||||
bool mInUpdate;
|
||||
nsIntSize mSize;
|
||||
unsigned int mTileSize;
|
||||
unsigned int mRows, mColumns;
|
||||
GLContext* mGL;
|
||||
PRBool mUseNearestFilter;
|
||||
// A temporary surface to faciliate cross-tile updates.
|
||||
nsRefPtr<gfxASurface> mUpdateSurface;
|
||||
// The region of update requested
|
||||
nsIntRegion mUpdateRegion;
|
||||
TextureState mTextureState;
|
||||
};
|
||||
|
||||
struct THEBES_API ContextFormat
|
||||
{
|
||||
static const ContextFormat BasicRGBA32Format;
|
||||
|
@ -706,6 +762,21 @@ public:
|
|||
GLenum aWrapMode,
|
||||
PRBool aUseNearestFilter=PR_FALSE);
|
||||
|
||||
/**
|
||||
* In EGL we want to use Tiled Texture Images, which we return
|
||||
* from CreateTextureImage above.
|
||||
* Inside TiledTextureImage we need to create actual images and to
|
||||
* prevent infinite recursion we need to differentiate the two
|
||||
* functions.
|
||||
**/
|
||||
virtual already_AddRefed<TextureImage>
|
||||
TileGenFunc(const nsIntSize& aSize,
|
||||
TextureImage::ContentType aContentType,
|
||||
PRBool aUseNearestFilter = PR_FALSE)
|
||||
{
|
||||
return nsnull;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read the image data contained in aTexture, and return it as an ImageSurface.
|
||||
* If GL_RGBA is given as the format, a ImageFormatARGB32 surface is returned.
|
||||
|
|
|
@ -821,13 +821,18 @@ public:
|
|||
{
|
||||
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
|
||||
}
|
||||
|
||||
// GLContext interface - returns Tiled Texture Image in our case
|
||||
virtual already_AddRefed<TextureImage>
|
||||
CreateTextureImage(const nsIntSize& aSize,
|
||||
TextureImage::ContentType aContentType,
|
||||
GLenum aWrapMode,
|
||||
PRBool aUseNearestFilter=PR_FALSE);
|
||||
|
||||
// a function to generate Tiles for Tiled Texture Image
|
||||
virtual already_AddRefed<TextureImage>
|
||||
TileGenFunc(const nsIntSize& aSize,
|
||||
TextureImage::ContentType aContentType,
|
||||
PRBool aUseNearestFilter = PR_FALSE);
|
||||
// hold a reference to the given surface
|
||||
// for the lifetime of this context.
|
||||
void HoldSurface(gfxASurface *aSurf) {
|
||||
|
@ -1108,7 +1113,8 @@ public:
|
|||
GLenum aWrapMode,
|
||||
ContentType aContentType,
|
||||
GLContext* aContext)
|
||||
: TextureImage(aTexture, aSize, aWrapMode, aContentType)
|
||||
: TextureImage(aSize, aWrapMode, aContentType)
|
||||
, mTexture(aTexture)
|
||||
, mGLContext(aContext)
|
||||
, mUpdateFormat(gfxASurface::ImageFormatUnknown)
|
||||
, mSurface(nsnull)
|
||||
|
@ -1302,7 +1308,7 @@ public:
|
|||
return; // mTexture is bound
|
||||
}
|
||||
|
||||
virtual bool DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion)
|
||||
virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */)
|
||||
{
|
||||
nsIntRect bounds = aRegion.GetBounds();
|
||||
|
||||
|
@ -1319,7 +1325,7 @@ public:
|
|||
if (mUpdateSurface) {
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(mUpdateSurface);
|
||||
gfxUtils::ClipToRegion(ctx, aRegion);
|
||||
ctx->SetSource(aSurf);
|
||||
ctx->SetSource(aSurf, gfxPoint(-aFrom.x, -aFrom.y));
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->Paint();
|
||||
mUpdateSurface = nsnull;
|
||||
|
@ -1331,7 +1337,7 @@ public:
|
|||
region,
|
||||
mTexture,
|
||||
!mCreated,
|
||||
bounds.TopLeft(),
|
||||
bounds.TopLeft() + aFrom,
|
||||
PR_FALSE);
|
||||
}
|
||||
|
||||
|
@ -1342,10 +1348,14 @@ public:
|
|||
virtual void BindTexture(GLenum aTextureUnit)
|
||||
{
|
||||
mGLContext->fActiveTexture(aTextureUnit);
|
||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, Texture());
|
||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
}
|
||||
|
||||
virtual GLuint GetTextureID() {
|
||||
return mTexture;
|
||||
};
|
||||
|
||||
virtual PRBool InUpdate() const { return !!mUpdateSurface; }
|
||||
|
||||
virtual void Resize(const nsIntSize& aSize)
|
||||
|
@ -1576,6 +1586,7 @@ protected:
|
|||
nsRefPtr<gfxASurface> mUpdateSurface;
|
||||
EGLSurface mSurface;
|
||||
EGLConfig mConfig;
|
||||
GLuint mTexture;
|
||||
EGLImageKHR mImageKHR;
|
||||
|
||||
PRPackedBool mCreated;
|
||||
|
@ -1588,6 +1599,15 @@ GLContextEGL::CreateTextureImage(const nsIntSize& aSize,
|
|||
TextureImage::ContentType aContentType,
|
||||
GLenum aWrapMode,
|
||||
PRBool aUseNearestFilter)
|
||||
{
|
||||
nsRefPtr<TextureImage> t = new gl::TiledTextureImage(this, aSize, aContentType);
|
||||
return t.forget();
|
||||
};
|
||||
|
||||
already_AddRefed<TextureImage>
|
||||
GLContextEGL::TileGenFunc(const nsIntSize& aSize,
|
||||
TextureImage::ContentType aContentType,
|
||||
PRBool aUseNearestFilter)
|
||||
{
|
||||
MakeCurrent();
|
||||
|
||||
|
@ -1598,13 +1618,13 @@ GLContextEGL::CreateTextureImage(const nsIntSize& aSize,
|
|||
fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
|
||||
|
||||
nsRefPtr<TextureImageEGL> teximage =
|
||||
new TextureImageEGL(texture, aSize, aWrapMode, aContentType, this);
|
||||
new TextureImageEGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, this);
|
||||
|
||||
GLint texfilter = aUseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, aWrapMode);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, aWrapMode);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
|
||||
return teximage.forget();
|
||||
}
|
||||
|
|
|
@ -552,11 +552,12 @@ public:
|
|||
mInUpdate = PR_FALSE;
|
||||
}
|
||||
|
||||
virtual bool DirectUpdate(gfxASurface* aSurface, const nsIntRegion& aRegion)
|
||||
|
||||
virtual bool DirectUpdate(gfxASurface* aSurface, const nsIntRegion& aRegion, const nsIntPoint& aFrom)
|
||||
{
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(mUpdateSurface);
|
||||
gfxUtils::ClipToRegion(ctx, aRegion);
|
||||
ctx->SetSource(aSurface);
|
||||
ctx->SetSource(aSurface, aFrom);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->Paint();
|
||||
return true;
|
||||
|
@ -565,7 +566,7 @@ public:
|
|||
virtual void BindTexture(GLenum aTextureUnit)
|
||||
{
|
||||
mGLContext->fActiveTexture(aTextureUnit);
|
||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, Texture());
|
||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||
sGLXLibrary.BindTexImage(mPixmap);
|
||||
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
}
|
||||
|
@ -583,6 +584,10 @@ public:
|
|||
|
||||
virtual PRBool InUpdate() const { return mInUpdate; }
|
||||
|
||||
virtual GLuint GetTextureID() {
|
||||
return mTexture;
|
||||
};
|
||||
|
||||
private:
|
||||
TextureImageGLX(GLuint aTexture,
|
||||
const nsIntSize& aSize,
|
||||
|
@ -591,11 +596,12 @@ private:
|
|||
GLContext* aContext,
|
||||
gfxASurface* aSurface,
|
||||
GLXPixmap aPixmap)
|
||||
: TextureImage(aTexture, aSize, aWrapMode, aContentType)
|
||||
: TextureImage(aSize, aWrapMode, aContentType)
|
||||
, mGLContext(aContext)
|
||||
, mUpdateSurface(aSurface)
|
||||
, mPixmap(aPixmap)
|
||||
, mInUpdate(PR_FALSE)
|
||||
, mTexture(aTexture)
|
||||
{
|
||||
if (aSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
|
||||
mShaderType = gl::RGBALayerProgramType;
|
||||
|
@ -608,6 +614,7 @@ private:
|
|||
nsRefPtr<gfxASurface> mUpdateSurface;
|
||||
GLXPixmap mPixmap;
|
||||
PRPackedBool mInUpdate;
|
||||
GLuint mTexture;
|
||||
};
|
||||
|
||||
already_AddRefed<TextureImage>
|
||||
|
|
|
@ -2073,8 +2073,7 @@ nsChildView::DrawOver(LayerManager* aManager, nsIntRect aRect)
|
|||
float bottomX = aRect.x + aRect.width;
|
||||
float bottomY = aRect.y + aRect.height;
|
||||
|
||||
manager->gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
manager->gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mResizerImage->Texture());
|
||||
TextureImage::ScopedBindTexture texBind(mResizerImage, LOCAL_GL_TEXTURE0);
|
||||
|
||||
ColorTextureLayerProgram *program =
|
||||
manager->GetColorTextureLayerProgram(mResizerImage->GetShaderProgramType());
|
||||
|
|
Загрузка…
Ссылка в новой задаче