Bug 671639 - Part 1: AttachIOSurface now updates the Framebuffer instead of recreating it. r=matt.woodrow

This commit is contained in:
Benoit Girard 2011-11-16 11:36:06 +13:00
parent 4242b3d2b9
commit 1d1b235efb
2 changed files with 73 additions and 34 deletions

View File

@ -93,6 +93,8 @@ public:
static void SaveToDisk(nsIOSurface *surf);
#endif
private:
void SetBounds(int aWidth, int aHeight);
void SetViewport(int aWidth, int aHeight);
void Destroy();
void *mCARenderer;

View File

@ -491,26 +491,8 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
return NS_ERROR_FAILURE;
}
// Create a transaction and disable animations
// to make the position update instant.
[CATransaction begin];
NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
[NSNull null], @"onOrderOut",
[NSNull null], @"sublayers",
[NSNull null], @"contents",
[NSNull null], @"position",
[NSNull null], @"bounds",
nil];
layer.actions = newActions;
[newActions release];
[CATransaction setValue: [NSNumber numberWithFloat:0.0f] forKey: kCATransactionAnimationDuration];
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
[layer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
[layer setPosition:CGPointMake(aWidth/2.0, aHeight/2.0)];
caRenderer.layer = layer;
caRenderer.bounds = CGRectMake(0, 0, aWidth, aHeight);
[CATransaction commit];
SetBounds(aWidth, aHeight);
// We target rendering to a CGImage if no shared IOSurface are given.
if (!mIOSurface) {
@ -599,14 +581,7 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
return NS_ERROR_FAILURE;
}
::glViewport(0.0, 0.0, aWidth, aHeight);
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
::glOrtho (0.0, aWidth, 0.0, aHeight, -1, 1);
// Render upside down to speed up CGContextDrawImage
::glTranslatef(0.0f, aHeight, 0.0);
::glScalef(1.0, -1.0, 1.0);
SetViewport(aWidth, aHeight);
GLenum result = ::glGetError();
if (result != GL_NO_ERROR) {
@ -625,21 +600,83 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
return NS_OK;
}
void nsCARenderer::SetBounds(int aWidth, int aHeight) {
CARenderer* caRenderer = (CARenderer*)mCARenderer;
CALayer* layer = [mCARenderer layer];
// Create a transaction and disable animations
// to make the position update instant.
[CATransaction begin];
NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
[NSNull null], @"onOrderOut",
[NSNull null], @"sublayers",
[NSNull null], @"contents",
[NSNull null], @"position",
[NSNull null], @"bounds",
nil];
layer.actions = newActions;
[newActions release];
[CATransaction setValue: [NSNumber numberWithFloat:0.0f] forKey: kCATransactionAnimationDuration];
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
[layer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
[layer setPosition:CGPointMake(aWidth/2.0, aHeight/2.0)];
caRenderer.bounds = CGRectMake(0, 0, aWidth, aHeight);
[CATransaction commit];
}
void nsCARenderer::SetViewport(int aWidth, int aHeight) {
::glViewport(0.0, 0.0, aWidth, aHeight);
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
::glOrtho (0.0, aWidth, 0.0, aHeight, -1, 1);
// Render upside down to speed up CGContextDrawImage
::glTranslatef(0.0f, aHeight, 0.0);
::glScalef(1.0, -1.0, 1.0);
}
void nsCARenderer::AttachIOSurface(nsRefPtr<nsIOSurface> aSurface) {
if (mIOSurface &&
if (mIOSurface &&
aSurface->GetIOSurfaceID() == mIOSurface->GetIOSurfaceID()) {
// This object isn't needed since we already have a
// handle to the same io surface.
aSurface = nsnull;
return;
}
if (mCARenderer) {
// We are attaching a larger IOSurface, we need to
// resize our elements.
Destroy();
}
mIOSurface = aSurface;
// Update the framebuffer and viewport
if (mCARenderer) {
CARenderer* caRenderer = (CARenderer*)mCARenderer;
int width = caRenderer.bounds.size.width;
int height = caRenderer.bounds.size.height;
CGLContextObj oldContext = ::CGLGetCurrentContext();
::CGLSetCurrentContext(mOpenGLContext);
::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mIOTexture);
nsIOSurfaceLib::CGLTexImageIOSurface2D(mOpenGLContext, GL_TEXTURE_RECTANGLE_ARB,
GL_RGBA, mIOSurface->GetWidth(), mIOSurface->GetHeight(),
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
mIOSurface->mIOSurfacePtr, 0);
::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
// Rebind the FBO to make it live
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
if (mIOSurface->GetWidth() != width || mIOSurface->GetHeight() != height) {
width = mIOSurface->GetWidth();
height = mIOSurface->GetHeight();
SetBounds(width, height);
SetViewport(width, height);
}
if (oldContext) {
::CGLSetCurrentContext(oldContext);
}
}
}
IOSurfaceID nsCARenderer::GetIOSurfaceID() {
@ -841,7 +878,7 @@ void nsCARenderer::SaveToDisk(nsIOSurface *surf) {
CFURLRef url = ::CFURLCreateWithString( NULL, cfStr, NULL);
CFStringRef type = kUTTypePNG;
size_t count = 1;
size_t count = 1;
CFDictionaryRef options = NULL;
CGImageDestinationRef dest = ::CGImageDestinationCreateWithURL(url, type, count, options);