зеркало из 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();
|
mOGLManager->MakeCurrent();
|
||||||
|
|
||||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
|
||||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexImage->Texture());
|
|
||||||
ColorTextureLayerProgram *program =
|
ColorTextureLayerProgram *program =
|
||||||
mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
|
mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
|
||||||
|
|
||||||
ApplyFilter(mFilter);
|
ApplyFilter(mFilter);
|
||||||
|
|
||||||
program->Activate();
|
program->Activate();
|
||||||
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mTexImage->GetSize()));
|
|
||||||
program->SetLayerTransform(GetEffectiveTransform());
|
program->SetLayerTransform(GetEffectiveTransform());
|
||||||
program->SetLayerOpacity(GetEffectiveOpacity());
|
program->SetLayerOpacity(GetEffectiveOpacity());
|
||||||
program->SetRenderOffset(aOffset);
|
program->SetRenderOffset(aOffset);
|
||||||
program->SetTextureUnit(0);
|
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();
|
mOGLManager->MakeCurrent();
|
||||||
|
|
||||||
LayerProgram* program;
|
|
||||||
|
|
||||||
if (mTexImage) {
|
if (mTexImage) {
|
||||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
|
||||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexImage->Texture());
|
|
||||||
ColorTextureLayerProgram *colorProgram =
|
ColorTextureLayerProgram *colorProgram =
|
||||||
mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
|
mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
|
||||||
|
|
||||||
ApplyFilter(mFilter);
|
|
||||||
|
|
||||||
colorProgram->Activate();
|
colorProgram->Activate();
|
||||||
colorProgram->SetTextureUnit(0);
|
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 {
|
} else {
|
||||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[0].GetTextureID());
|
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[0].GetTextureID());
|
||||||
|
@ -962,7 +962,7 @@ ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE2);
|
gl()->fActiveTexture(LOCAL_GL_TEXTURE2);
|
||||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[2].GetTextureID());
|
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[2].GetTextureID());
|
||||||
ApplyFilter(mFilter);
|
ApplyFilter(mFilter);
|
||||||
|
|
||||||
YCbCrTextureLayerProgram *yuvProgram = mOGLManager->GetYCbCrLayerProgram();
|
YCbCrTextureLayerProgram *yuvProgram = mOGLManager->GetYCbCrLayerProgram();
|
||||||
|
|
||||||
yuvProgram->Activate();
|
yuvProgram->Activate();
|
||||||
|
@ -970,24 +970,14 @@ ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||||
mPictureRect.width,
|
mPictureRect.width,
|
||||||
mPictureRect.height));
|
mPictureRect.height));
|
||||||
yuvProgram->SetYCbCrTextureUnits(0, 1, 2);
|
yuvProgram->SetYCbCrTextureUnits(0, 1, 2);
|
||||||
|
yuvProgram->SetLayerTransform(GetEffectiveTransform());
|
||||||
|
yuvProgram->SetLayerOpacity(GetEffectiveOpacity());
|
||||||
|
yuvProgram->SetRenderOffset(aOffset);
|
||||||
|
|
||||||
program = yuvProgram;
|
mOGLManager->BindAndDrawQuadWithTextureRect(yuvProgram,
|
||||||
program->SetLayerTransform(GetEffectiveTransform());
|
|
||||||
program->SetLayerOpacity(GetEffectiveOpacity());
|
|
||||||
program->SetRenderOffset(aOffset);
|
|
||||||
|
|
||||||
mOGLManager->BindAndDrawQuadWithTextureRect(program,
|
|
||||||
mPictureRect,
|
mPictureRect,
|
||||||
nsIntSize(mSize.width, mSize.height));
|
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();
|
mTexImageOnWhite->EndUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind textures.
|
|
||||||
TextureImage::ScopedBindTexture texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
|
||||||
TextureImage::ScopedBindTexture texOnWhiteBind(mTexImageOnWhite, LOCAL_GL_TEXTURE1);
|
|
||||||
|
|
||||||
PRInt32 passes = mTexImageOnWhite ? 2 : 1;
|
PRInt32 passes = mTexImageOnWhite ? 2 : 1;
|
||||||
for (PRInt32 pass = 1; pass <= passes; ++pass) {
|
for (PRInt32 pass = 1; pass <= passes; ++pass) {
|
||||||
LayerProgram *program;
|
LayerProgram *program;
|
||||||
|
@ -194,17 +190,42 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
|
||||||
} else {
|
} else {
|
||||||
renderRegion = &visibleRegion;
|
renderRegion = &visibleRegion;
|
||||||
}
|
}
|
||||||
nsIntRegionRectIterator iter(*renderRegion);
|
|
||||||
while (const nsIntRect *iterRect = iter.Next()) {
|
|
||||||
nsIntRect quadRect = *iterRect;
|
|
||||||
program->SetLayerQuadRect(quadRect);
|
|
||||||
|
|
||||||
quadRect.MoveBy(-GetOriginOffset());
|
mTexImage->BeginTileIteration();
|
||||||
|
if (mTexImageOnWhite) {
|
||||||
aManager->BindAndDrawQuadWithTextureRect(program, quadRect,
|
mTexImageOnWhite->BeginTileIteration();
|
||||||
mTexImage->GetSize(),
|
NS_ASSERTION(mTexImageOnWhite->GetTileRect() == mTexImage->GetTileRect(), "component alpha textures should be the same size.");
|
||||||
mTexImage->GetWrapMode());
|
|
||||||
}
|
}
|
||||||
|
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 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);
|
||||||
|
|
||||||
|
regionRect.MoveBy(-mTexImage->GetTileRect().TopLeft()); // get region of tile
|
||||||
|
aManager->BindAndDrawQuadWithTextureRect(program, regionRect,
|
||||||
|
textureRect.Size(),
|
||||||
|
mTexImage->GetWrapMode());
|
||||||
|
}
|
||||||
|
} while (mTexImage->NextTile());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTexImageOnWhite) {
|
if (mTexImageOnWhite) {
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "GLContextProvider.h"
|
#include "GLContextProvider.h"
|
||||||
|
|
||||||
#include "gfxCrashReporterUtils.h"
|
#include "gfxCrashReporterUtils.h"
|
||||||
|
#include "gfxUtils.h"
|
||||||
|
|
||||||
#include "mozilla/Util.h" // for DebugOnly
|
#include "mozilla/Util.h" // for DebugOnly
|
||||||
|
|
||||||
|
@ -636,7 +637,7 @@ void
|
||||||
BasicTextureImage::BindTexture(GLenum aTextureUnit)
|
BasicTextureImage::BindTexture(GLenum aTextureUnit)
|
||||||
{
|
{
|
||||||
mGLContext->fActiveTexture(aTextureUnit);
|
mGLContext->fActiveTexture(aTextureUnit);
|
||||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, Texture());
|
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||||
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,7 +660,7 @@ BasicTextureImage::FinishedSurfaceUpload()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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();
|
nsIntRect bounds = aRegion.GetBounds();
|
||||||
nsIntRegion region;
|
nsIntRegion region;
|
||||||
|
@ -675,7 +676,7 @@ BasicTextureImage::DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion)
|
||||||
region,
|
region,
|
||||||
mTexture,
|
mTexture,
|
||||||
mTextureState == Created,
|
mTextureState == Created,
|
||||||
bounds.TopLeft(),
|
bounds.TopLeft() + aFrom,
|
||||||
PR_FALSE);
|
PR_FALSE);
|
||||||
mTextureState = Valid;
|
mTextureState = Valid;
|
||||||
return true;
|
return true;
|
||||||
|
@ -702,6 +703,202 @@ BasicTextureImage::Resize(const nsIntSize& aSize)
|
||||||
mSize = 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
|
PRBool
|
||||||
GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
|
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(!aSrc->InUpdate(), "Source texture is in update!");
|
||||||
NS_ASSERTION(!aDst->InUpdate(), "Destination 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
|
// only save/restore this stuff on Qualcomm Adreno, to work
|
||||||
// around an apparent bug
|
// around an apparent bug
|
||||||
int savedFb = 0;
|
int savedFb = 0;
|
||||||
|
@ -1255,57 +1455,114 @@ GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
|
||||||
fDisable(LOCAL_GL_SCISSOR_TEST);
|
fDisable(LOCAL_GL_SCISSOR_TEST);
|
||||||
fDisable(LOCAL_GL_BLEND);
|
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);
|
||||||
|
|
||||||
UseBlitProgram();
|
// 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);
|
||||||
|
|
||||||
nsIntSize srcSize = aSrc->GetSize();
|
// this tile is not part of the destination rectangle aDstRect
|
||||||
nsIntSize dstSize = aDst->GetSize();
|
if (dstSubRect.IsEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
PushViewportRect(nsIntRect(0, 0, dstSize.width, dstSize.height));
|
// (*) 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());
|
||||||
|
|
||||||
float dx0 = 2.0 * float(aDstRect.x) / float(dstSize.width) - 1.0;
|
SetBlitFramebufferForDestTexture(aDst->GetTextureID());
|
||||||
float dy0 = 2.0 * float(aDstRect.y) / float(dstSize.height) - 1.0;
|
UseBlitProgram();
|
||||||
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;
|
aSrc->BeginTileIteration();
|
||||||
if (aSrc->GetWrapMode() == LOCAL_GL_REPEAT) {
|
// now iterate over all tiles in the source Image...
|
||||||
rects.addRect(/* dest rectangle */
|
do {
|
||||||
dx0, dy0, dx1, dy1,
|
// calculate portion of the source tile that is in the source rect
|
||||||
/* tex coords */
|
nsIntRect srcSubRect;
|
||||||
aSrcRect.x / float(srcSize.width),
|
nsIntRect srcTextureRect = aSrc->GetTileRect();
|
||||||
aSrcRect.y / float(srcSize.height),
|
srcSubRect.IntersectRect(aSrcRect, srcTextureRect);
|
||||||
aSrcRect.XMost() / float(srcSize.width),
|
|
||||||
aSrcRect.YMost() / float(srcSize.height));
|
|
||||||
} else {
|
|
||||||
DecomposeIntoNoRepeatTriangles(aSrcRect, srcSize, rects);
|
|
||||||
|
|
||||||
// now put the coords into the d[xy]0 .. d[xy]1 coordinate space
|
// this tile is not part of the source rect
|
||||||
// from the 0..1 that it comes out of decompose
|
if (srcSubRect.IsEmpty()) {
|
||||||
RectTriangles::vert_coord* v = (RectTriangles::vert_coord*)rects.vertexPointer();
|
continue;
|
||||||
for (int i = 0; i < rects.elements(); ++i) {
|
}
|
||||||
v[i].x = (v[i].x * (dx1 - dx0)) + dx0;
|
// calculate intersection of source rect with destination rect
|
||||||
v[i].y = (v[i].y * (dy1 - dy0)) + dy0;
|
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);
|
||||||
|
|
||||||
fActiveTexture(LOCAL_GL_TEXTURE0);
|
float dx0 = 2.0 * float(srcSubInDstRect.x) / float(dstSize.width) - 1.0;
|
||||||
fBindTexture(LOCAL_GL_TEXTURE_2D, aSrc->Texture());
|
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));
|
||||||
|
|
||||||
fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
RectTriangles rects;
|
||||||
|
if (aSrc->GetWrapMode() == LOCAL_GL_REPEAT) {
|
||||||
|
rects.addRect(/* dest rectangle */
|
||||||
|
dx0, dy0, dx1, dy1,
|
||||||
|
/* tex coords */
|
||||||
|
srcSubRect.x / float(srcSize.width),
|
||||||
|
srcSubRect.y / float(srcSize.height),
|
||||||
|
srcSubRect.XMost() / float(srcSize.width),
|
||||||
|
srcSubRect.YMost() / float(srcSize.height));
|
||||||
|
} else {
|
||||||
|
DecomposeIntoNoRepeatTriangles(srcSubRect, srcSize, rects);
|
||||||
|
|
||||||
fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.vertexPointer());
|
// now put the coords into the d[xy]0 .. d[xy]1 coordinate space
|
||||||
fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.texCoordPointer());
|
// from the 0..1 that it comes out of decompose
|
||||||
|
RectTriangles::vert_coord* v = (RectTriangles::vert_coord*)rects.vertexPointer();
|
||||||
|
|
||||||
fEnableVertexAttribArray(0);
|
for (unsigned int i = 0; i < rects.elements(); ++i) {
|
||||||
fEnableVertexAttribArray(1);
|
v[i].x = (v[i].x * (dx1 - dx0)) + dx0;
|
||||||
|
v[i].y = (v[i].y * (dy1 - dy0)) + dy0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fDrawArrays(LOCAL_GL_TRIANGLES, 0, rects.elements());
|
TextureImage::ScopedBindTexture texBind(aSrc, LOCAL_GL_TEXTURE0);
|
||||||
|
|
||||||
fDisableVertexAttribArray(0);
|
fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||||
fDisableVertexAttribArray(1);
|
|
||||||
|
fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.vertexPointer());
|
||||||
|
fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.texCoordPointer());
|
||||||
|
|
||||||
|
fEnableVertexAttribArray(0);
|
||||||
|
fEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
fDrawArrays(LOCAL_GL_TRIANGLES, 0, rects.elements());
|
||||||
|
|
||||||
|
fDisableVertexAttribArray(0);
|
||||||
|
fDisableVertexAttribArray(1);
|
||||||
|
|
||||||
|
PopViewportRect();
|
||||||
|
} while (aSrc->NextTile());
|
||||||
|
} while (aDst->NextTile());
|
||||||
|
|
||||||
fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, NULL);
|
fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, NULL);
|
||||||
fVertexAttribPointer(1, 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_SCISSOR_TEST);
|
||||||
fEnable(LOCAL_GL_BLEND);
|
fEnable(LOCAL_GL_BLEND);
|
||||||
|
|
||||||
PopViewportRect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
|
|
|
@ -75,8 +75,12 @@ typedef char realGLboolean;
|
||||||
#include "GLContextSymbols.h"
|
#include "GLContextSymbols.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gl {
|
namespace layers {
|
||||||
|
class LayerManagerOGL;
|
||||||
|
class ColorTextureLayerProgram;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace gl {
|
||||||
class GLContext;
|
class GLContext;
|
||||||
|
|
||||||
class LibrarySymbolLoader
|
class LibrarySymbolLoader
|
||||||
|
@ -156,6 +160,13 @@ class TextureImage
|
||||||
{
|
{
|
||||||
NS_INLINE_DECL_REFCOUNTING(TextureImage)
|
NS_INLINE_DECL_REFCOUNTING(TextureImage)
|
||||||
public:
|
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;
|
typedef gfxASurface::gfxContentType ContentType;
|
||||||
|
|
||||||
virtual ~TextureImage() {}
|
virtual ~TextureImage() {}
|
||||||
|
@ -191,6 +202,22 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void EndUpdate() = 0;
|
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
|
* Set this TextureImage's size, and ensure a texture has been
|
||||||
* allocated. Must not be called between BeginUpdate and EndUpdate.
|
* allocated. Must not be called between BeginUpdate and EndUpdate.
|
||||||
|
@ -206,7 +233,12 @@ public:
|
||||||
EndUpdate();
|
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 BindTexture(GLenum aTextureUnit) = 0;
|
||||||
virtual void ReleaseTexture() {};
|
virtual void ReleaseTexture() {};
|
||||||
|
@ -233,16 +265,6 @@ public:
|
||||||
TextureImage *mTexture;
|
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
|
* Returns the shader program type that should be used to render
|
||||||
|
@ -279,17 +301,15 @@ protected:
|
||||||
* TextureImage from GLContext::CreateTextureImage(). That is,
|
* TextureImage from GLContext::CreateTextureImage(). That is,
|
||||||
* clients must not be given partially-constructed TextureImages.
|
* clients must not be given partially-constructed TextureImages.
|
||||||
*/
|
*/
|
||||||
TextureImage(GLuint aTexture, const nsIntSize& aSize,
|
TextureImage(const nsIntSize& aSize,
|
||||||
GLenum aWrapMode, ContentType aContentType,
|
GLenum aWrapMode, ContentType aContentType,
|
||||||
PRBool aIsRGB = PR_FALSE)
|
PRBool aIsRGB = PR_FALSE)
|
||||||
: mTexture(aTexture)
|
: mSize(aSize)
|
||||||
, mSize(aSize)
|
|
||||||
, mWrapMode(aWrapMode)
|
, mWrapMode(aWrapMode)
|
||||||
, mContentType(aContentType)
|
, mContentType(aContentType)
|
||||||
, mIsRGBFormat(aIsRGB)
|
, mIsRGBFormat(aIsRGB)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GLuint mTexture;
|
|
||||||
nsIntSize mSize;
|
nsIntSize mSize;
|
||||||
GLenum mWrapMode;
|
GLenum mWrapMode;
|
||||||
ContentType mContentType;
|
ContentType mContentType;
|
||||||
|
@ -318,25 +338,19 @@ public:
|
||||||
GLenum aWrapMode,
|
GLenum aWrapMode,
|
||||||
ContentType aContentType,
|
ContentType aContentType,
|
||||||
GLContext* aContext)
|
GLContext* aContext)
|
||||||
: TextureImage(aTexture, aSize, aWrapMode, aContentType)
|
: TextureImage(aSize, aWrapMode, aContentType)
|
||||||
|
, mTexture(aTexture)
|
||||||
, mTextureState(Created)
|
, mTextureState(Created)
|
||||||
, mGLContext(aContext)
|
, mGLContext(aContext)
|
||||||
, mUpdateOffset(0, 0)
|
, 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 void BindTexture(GLenum aTextureUnit);
|
||||||
|
|
||||||
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
|
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
|
||||||
virtual void EndUpdate();
|
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
|
// Returns a surface to draw into
|
||||||
virtual already_AddRefed<gfxASurface>
|
virtual already_AddRefed<gfxASurface>
|
||||||
GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
|
GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
|
||||||
|
@ -354,6 +368,7 @@ public:
|
||||||
virtual void Resize(const nsIntSize& aSize);
|
virtual void Resize(const nsIntSize& aSize);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
GLuint mTexture;
|
||||||
TextureState mTextureState;
|
TextureState mTextureState;
|
||||||
GLContext* mGLContext;
|
GLContext* mGLContext;
|
||||||
nsRefPtr<gfxASurface> mUpdateSurface;
|
nsRefPtr<gfxASurface> mUpdateSurface;
|
||||||
|
@ -363,6 +378,47 @@ protected:
|
||||||
nsIntPoint mUpdateOffset;
|
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
|
struct THEBES_API ContextFormat
|
||||||
{
|
{
|
||||||
static const ContextFormat BasicRGBA32Format;
|
static const ContextFormat BasicRGBA32Format;
|
||||||
|
@ -706,6 +762,21 @@ public:
|
||||||
GLenum aWrapMode,
|
GLenum aWrapMode,
|
||||||
PRBool aUseNearestFilter=PR_FALSE);
|
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.
|
* 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.
|
* If GL_RGBA is given as the format, a ImageFormatARGB32 surface is returned.
|
||||||
|
|
|
@ -821,13 +821,18 @@ public:
|
||||||
{
|
{
|
||||||
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
|
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
|
||||||
}
|
}
|
||||||
|
// GLContext interface - returns Tiled Texture Image in our case
|
||||||
virtual already_AddRefed<TextureImage>
|
virtual already_AddRefed<TextureImage>
|
||||||
CreateTextureImage(const nsIntSize& aSize,
|
CreateTextureImage(const nsIntSize& aSize,
|
||||||
TextureImage::ContentType aContentType,
|
TextureImage::ContentType aContentType,
|
||||||
GLenum aWrapMode,
|
GLenum aWrapMode,
|
||||||
PRBool aUseNearestFilter=PR_FALSE);
|
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
|
// hold a reference to the given surface
|
||||||
// for the lifetime of this context.
|
// for the lifetime of this context.
|
||||||
void HoldSurface(gfxASurface *aSurf) {
|
void HoldSurface(gfxASurface *aSurf) {
|
||||||
|
@ -1108,7 +1113,8 @@ public:
|
||||||
GLenum aWrapMode,
|
GLenum aWrapMode,
|
||||||
ContentType aContentType,
|
ContentType aContentType,
|
||||||
GLContext* aContext)
|
GLContext* aContext)
|
||||||
: TextureImage(aTexture, aSize, aWrapMode, aContentType)
|
: TextureImage(aSize, aWrapMode, aContentType)
|
||||||
|
, mTexture(aTexture)
|
||||||
, mGLContext(aContext)
|
, mGLContext(aContext)
|
||||||
, mUpdateFormat(gfxASurface::ImageFormatUnknown)
|
, mUpdateFormat(gfxASurface::ImageFormatUnknown)
|
||||||
, mSurface(nsnull)
|
, mSurface(nsnull)
|
||||||
|
@ -1302,10 +1308,10 @@ public:
|
||||||
return; // mTexture is bound
|
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();
|
nsIntRect bounds = aRegion.GetBounds();
|
||||||
|
|
||||||
nsIntRegion region;
|
nsIntRegion region;
|
||||||
if (!mCreated) {
|
if (!mCreated) {
|
||||||
bounds = nsIntRect(0, 0, mSize.width, mSize.height);
|
bounds = nsIntRect(0, 0, mSize.width, mSize.height);
|
||||||
|
@ -1319,7 +1325,7 @@ public:
|
||||||
if (mUpdateSurface) {
|
if (mUpdateSurface) {
|
||||||
nsRefPtr<gfxContext> ctx = new gfxContext(mUpdateSurface);
|
nsRefPtr<gfxContext> ctx = new gfxContext(mUpdateSurface);
|
||||||
gfxUtils::ClipToRegion(ctx, aRegion);
|
gfxUtils::ClipToRegion(ctx, aRegion);
|
||||||
ctx->SetSource(aSurf);
|
ctx->SetSource(aSurf, gfxPoint(-aFrom.x, -aFrom.y));
|
||||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||||
ctx->Paint();
|
ctx->Paint();
|
||||||
mUpdateSurface = nsnull;
|
mUpdateSurface = nsnull;
|
||||||
|
@ -1331,7 +1337,7 @@ public:
|
||||||
region,
|
region,
|
||||||
mTexture,
|
mTexture,
|
||||||
!mCreated,
|
!mCreated,
|
||||||
bounds.TopLeft(),
|
bounds.TopLeft() + aFrom,
|
||||||
PR_FALSE);
|
PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1342,10 +1348,14 @@ public:
|
||||||
virtual void BindTexture(GLenum aTextureUnit)
|
virtual void BindTexture(GLenum aTextureUnit)
|
||||||
{
|
{
|
||||||
mGLContext->fActiveTexture(aTextureUnit);
|
mGLContext->fActiveTexture(aTextureUnit);
|
||||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, Texture());
|
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||||
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual GLuint GetTextureID() {
|
||||||
|
return mTexture;
|
||||||
|
};
|
||||||
|
|
||||||
virtual PRBool InUpdate() const { return !!mUpdateSurface; }
|
virtual PRBool InUpdate() const { return !!mUpdateSurface; }
|
||||||
|
|
||||||
virtual void Resize(const nsIntSize& aSize)
|
virtual void Resize(const nsIntSize& aSize)
|
||||||
|
@ -1576,6 +1586,7 @@ protected:
|
||||||
nsRefPtr<gfxASurface> mUpdateSurface;
|
nsRefPtr<gfxASurface> mUpdateSurface;
|
||||||
EGLSurface mSurface;
|
EGLSurface mSurface;
|
||||||
EGLConfig mConfig;
|
EGLConfig mConfig;
|
||||||
|
GLuint mTexture;
|
||||||
EGLImageKHR mImageKHR;
|
EGLImageKHR mImageKHR;
|
||||||
|
|
||||||
PRPackedBool mCreated;
|
PRPackedBool mCreated;
|
||||||
|
@ -1588,6 +1599,15 @@ GLContextEGL::CreateTextureImage(const nsIntSize& aSize,
|
||||||
TextureImage::ContentType aContentType,
|
TextureImage::ContentType aContentType,
|
||||||
GLenum aWrapMode,
|
GLenum aWrapMode,
|
||||||
PRBool aUseNearestFilter)
|
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();
|
MakeCurrent();
|
||||||
|
|
||||||
|
@ -1598,13 +1618,13 @@ GLContextEGL::CreateTextureImage(const nsIntSize& aSize,
|
||||||
fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
|
fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
|
||||||
|
|
||||||
nsRefPtr<TextureImageEGL> teximage =
|
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;
|
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_MIN_FILTER, texfilter);
|
||||||
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_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_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||||
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, aWrapMode);
|
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
return teximage.forget();
|
return teximage.forget();
|
||||||
}
|
}
|
||||||
|
|
|
@ -552,11 +552,12 @@ public:
|
||||||
mInUpdate = PR_FALSE;
|
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);
|
nsRefPtr<gfxContext> ctx = new gfxContext(mUpdateSurface);
|
||||||
gfxUtils::ClipToRegion(ctx, aRegion);
|
gfxUtils::ClipToRegion(ctx, aRegion);
|
||||||
ctx->SetSource(aSurface);
|
ctx->SetSource(aSurface, aFrom);
|
||||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||||
ctx->Paint();
|
ctx->Paint();
|
||||||
return true;
|
return true;
|
||||||
|
@ -565,7 +566,7 @@ public:
|
||||||
virtual void BindTexture(GLenum aTextureUnit)
|
virtual void BindTexture(GLenum aTextureUnit)
|
||||||
{
|
{
|
||||||
mGLContext->fActiveTexture(aTextureUnit);
|
mGLContext->fActiveTexture(aTextureUnit);
|
||||||
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, Texture());
|
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||||
sGLXLibrary.BindTexImage(mPixmap);
|
sGLXLibrary.BindTexImage(mPixmap);
|
||||||
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
@ -583,6 +584,10 @@ public:
|
||||||
|
|
||||||
virtual PRBool InUpdate() const { return mInUpdate; }
|
virtual PRBool InUpdate() const { return mInUpdate; }
|
||||||
|
|
||||||
|
virtual GLuint GetTextureID() {
|
||||||
|
return mTexture;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextureImageGLX(GLuint aTexture,
|
TextureImageGLX(GLuint aTexture,
|
||||||
const nsIntSize& aSize,
|
const nsIntSize& aSize,
|
||||||
|
@ -591,11 +596,12 @@ private:
|
||||||
GLContext* aContext,
|
GLContext* aContext,
|
||||||
gfxASurface* aSurface,
|
gfxASurface* aSurface,
|
||||||
GLXPixmap aPixmap)
|
GLXPixmap aPixmap)
|
||||||
: TextureImage(aTexture, aSize, aWrapMode, aContentType)
|
: TextureImage(aSize, aWrapMode, aContentType)
|
||||||
, mGLContext(aContext)
|
, mGLContext(aContext)
|
||||||
, mUpdateSurface(aSurface)
|
, mUpdateSurface(aSurface)
|
||||||
, mPixmap(aPixmap)
|
, mPixmap(aPixmap)
|
||||||
, mInUpdate(PR_FALSE)
|
, mInUpdate(PR_FALSE)
|
||||||
|
, mTexture(aTexture)
|
||||||
{
|
{
|
||||||
if (aSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
|
if (aSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
|
||||||
mShaderType = gl::RGBALayerProgramType;
|
mShaderType = gl::RGBALayerProgramType;
|
||||||
|
@ -608,6 +614,7 @@ private:
|
||||||
nsRefPtr<gfxASurface> mUpdateSurface;
|
nsRefPtr<gfxASurface> mUpdateSurface;
|
||||||
GLXPixmap mPixmap;
|
GLXPixmap mPixmap;
|
||||||
PRPackedBool mInUpdate;
|
PRPackedBool mInUpdate;
|
||||||
|
GLuint mTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
already_AddRefed<TextureImage>
|
already_AddRefed<TextureImage>
|
||||||
|
|
|
@ -2073,8 +2073,7 @@ nsChildView::DrawOver(LayerManager* aManager, nsIntRect aRect)
|
||||||
float bottomX = aRect.x + aRect.width;
|
float bottomX = aRect.x + aRect.width;
|
||||||
float bottomY = aRect.y + aRect.height;
|
float bottomY = aRect.y + aRect.height;
|
||||||
|
|
||||||
manager->gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
TextureImage::ScopedBindTexture texBind(mResizerImage, LOCAL_GL_TEXTURE0);
|
||||||
manager->gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mResizerImage->Texture());
|
|
||||||
|
|
||||||
ColorTextureLayerProgram *program =
|
ColorTextureLayerProgram *program =
|
||||||
manager->GetColorTextureLayerProgram(mResizerImage->GetShaderProgramType());
|
manager->GetColorTextureLayerProgram(mResizerImage->GetShaderProgramType());
|
||||||
|
|
Загрузка…
Ссылка в новой задаче