Bug 627656 - Rather than creating a new texture for the resizer every draw and then deleting it once we're done, create a texture once on our first draw, then hold on to it until our widget is deleted. r=jrmuizel,mattwoodrow a=jrmuizel

This commit is contained in:
Joe Drew 2011-02-19 17:23:02 -05:00
parent fac1072e47
commit 95338b5170
2 changed files with 73 additions and 43 deletions

View File

@ -71,6 +71,12 @@ class nsChildView;
class nsCocoaWindow;
union nsPluginPort;
namespace mozilla {
namespace gl {
class TextureImage;
}
}
#ifndef NP_NO_CARBON
enum {
// Currently focused ChildView (while this TSM document is active).
@ -460,6 +466,7 @@ protected:
#endif
nsRefPtr<gfxASurface> mTempThebesSurface;
nsRefPtr<mozilla::gl::TextureImage> mResizerImage;
PRPackedBool mVisible;
PRPackedBool mDrawing;

View File

@ -518,6 +518,8 @@ nsChildView::~nsChildView()
NS_WARN_IF_FALSE(mOnDestroyCalled, "nsChildView object destroyed without calling Destroy()");
mResizerImage = nsnull;
// An nsChildView object that was in use can be destroyed without Destroy()
// ever being called on it. So we also need to do a quick, safe cleanup
// here (it's too late to just call Destroy(), which can cause crashes).
@ -2096,6 +2098,39 @@ nsChildView::GetThebesSurface()
return mTempThebesSurface;
}
static void
DrawResizer(CGContextRef aCtx)
{
CGContextSetShouldAntialias(aCtx, false);
CGPoint points[6];
points[0] = CGPointMake(13.0f, 4.0f);
points[1] = CGPointMake(3.0f, 14.0f);
points[2] = CGPointMake(13.0f, 8.0f);
points[3] = CGPointMake(7.0f, 14.0f);
points[4] = CGPointMake(13.0f, 12.0f);
points[5] = CGPointMake(11.0f, 14.0f);
CGContextSetRGBStrokeColor(aCtx, 0.00f, 0.00f, 0.00f, 0.15f);
CGContextStrokeLineSegments(aCtx, points, 6);
points[0] = CGPointMake(13.0f, 5.0f);
points[1] = CGPointMake(4.0f, 14.0f);
points[2] = CGPointMake(13.0f, 9.0f);
points[3] = CGPointMake(8.0f, 14.0f);
points[4] = CGPointMake(13.0f, 13.0f);
points[5] = CGPointMake(12.0f, 14.0f);
CGContextSetRGBStrokeColor(aCtx, 0.13f, 0.13f, 0.13f, 0.54f);
CGContextStrokeLineSegments(aCtx, points, 6);
points[0] = CGPointMake(13.0f, 6.0f);
points[1] = CGPointMake(5.0f, 14.0f);
points[2] = CGPointMake(13.0f, 10.0f);
points[3] = CGPointMake(9.0f, 14.0f);
points[5] = CGPointMake(13.0f, 13.9f);
points[4] = CGPointMake(13.0f, 14.0f);
CGContextSetRGBStrokeColor(aCtx, 0.84f, 0.84f, 0.84f, 0.55f);
CGContextStrokeLineSegments(aCtx, points, 6);
}
void
nsChildView::DrawOver(LayerManager* aManager, nsIntRect aRect)
{
@ -2108,53 +2143,42 @@ nsChildView::DrawOver(LayerManager* aManager, nsIntRect aRect)
return;
}
if (!mResizerImage) {
mResizerImage = manager->gl()->CreateTextureImage(nsIntSize(15, 15),
gfxASurface::CONTENT_COLOR_ALPHA,
LOCAL_GL_CLAMP_TO_EDGE,
/* aUseNearestFilter = */ PR_TRUE);
// Creation of texture images can fail.
if (!mResizerImage)
return;
nsIntRegion update(nsIntRect(0, 0, 15, 15));
gfxASurface *asurf = mResizerImage->BeginUpdate(update);
if (!asurf) {
mResizerImage = nsnull;
return;
}
NS_ABORT_IF_FALSE(asurf->GetType() == gfxASurface::SurfaceTypeQuartz,
"BeginUpdate must return a Quartz surface!");
nsRefPtr<gfxQuartzSurface> image = static_cast<gfxQuartzSurface*>(asurf);
DrawResizer(image->GetCGContext());
mResizerImage->EndUpdate();
}
NS_ABORT_IF_FALSE(mResizerImage, "Must have a texture allocated by now!");
float bottomX = aRect.x + aRect.width;
float bottomY = aRect.y + aRect.height;
nsRefPtr<gfxQuartzSurface> image =
new gfxQuartzSurface(gfxIntSize(15, 15), gfxASurface::ImageFormatARGB32);
CGContextRef ctx = image->GetCGContext();
CGContextSetShouldAntialias(ctx, false);
CGPoint points[6];
points[0] = CGPointMake(13.0f, 4.0f);
points[1] = CGPointMake(3.0f, 14.0f);
points[2] = CGPointMake(13.0f, 8.0f);
points[3] = CGPointMake(7.0f, 14.0f);
points[4] = CGPointMake(13.0f, 12.0f);
points[5] = CGPointMake(11.0f, 14.0f);
CGContextSetRGBStrokeColor(ctx, 0.00f, 0.00f, 0.00f, 0.15f);
CGContextStrokeLineSegments(ctx, points, 6);
points[0] = CGPointMake(13.0f, 5.0f);
points[1] = CGPointMake(4.0f, 14.0f);
points[2] = CGPointMake(13.0f, 9.0f);
points[3] = CGPointMake(8.0f, 14.0f);
points[4] = CGPointMake(13.0f, 13.0f);
points[5] = CGPointMake(12.0f, 14.0f);
CGContextSetRGBStrokeColor(ctx, 0.13f, 0.13f, 0.13f, 0.54f);
CGContextStrokeLineSegments(ctx, points, 6);
points[0] = CGPointMake(13.0f, 6.0f);
points[1] = CGPointMake(5.0f, 14.0f);
points[2] = CGPointMake(13.0f, 10.0f);
points[3] = CGPointMake(9.0f, 14.0f);
points[5] = CGPointMake(13.0f, 13.9f);
points[4] = CGPointMake(13.0f, 14.0f);
CGContextSetRGBStrokeColor(ctx, 0.84f, 0.84f, 0.84f, 0.55f);
CGContextStrokeLineSegments(ctx, points, 6);
GLuint tex = 0;
ShaderProgramType shader =
#ifdef MOZ_ENABLE_LIBXUL
manager->gl()->UploadSurfaceToTexture(image, nsIntRect(0, 0, 15, 15), tex);
#else
manager->gl()->UploadSurfaceToTextureExternal(image, nsIntRect(0, 0, 15, 15), tex);
#endif
manager->gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
manager->gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mResizerImage->Texture());
ColorTextureLayerProgram *program =
manager->GetColorTextureLayerProgram(shader);
manager->GetColorTextureLayerProgram(mResizerImage->GetShaderProgramType());
program->Activate();
program->SetLayerQuadRect(nsIntRect(bottomX - 15,
bottomY - 15,
@ -2166,7 +2190,6 @@ nsChildView::DrawOver(LayerManager* aManager, nsIntRect aRect)
program->SetTextureUnit(0);
manager->BindAndDrawQuad(program);
manager->gl()->fDeleteTextures(1, &tex);
}
void