//----------------------------------------------------------------------------//
void OpenGLApplePBTextureTarget::declareRenderSize(const Size& sz)
{
    // exit if current size is enough
    if ((d_area.getWidth() >= sz.d_width) &&
            (d_area.getHeight() >= sz.d_height))
        return;

    setArea(Rect(d_area.getPosition(), d_owner.getAdjustedTextureSize(sz)));

    // dump any previous pbuffer
    if (d_pbuffer)
    {
        CGLDestroyPBuffer(d_pbuffer);
        d_pbuffer = 0;
    }

    CGLError err;
    if (err = CGLCreatePBuffer(d_area.getWidth(), d_area.getHeight(),
                               GL_TEXTURE_2D, GL_RGBA, 0, &d_pbuffer))
    {
        CEGUI_THROW(RendererException(
                        "OpenGLApplePBTextureTarget::declareRenderSize "
                        "- CGLCreatePBuffer failed: " + String(CGLErrorString(err))));
    }

    if (err = CGLSetPBuffer(d_context, d_pbuffer, 0, 0, d_screen))
        CEGUI_THROW(RendererException(
                        "OpenGLApplePBTextureTarget::declareRenderSize "
                        "- CGLSetPBuffer failed: " + String(CGLErrorString(err))));

    clear();

    // make d_texture use the pbuffer as it's data source
    // save old texture binding
    GLuint old_tex;
    glGetIntegerv(GL_TEXTURE_BINDING_2D, reinterpret_cast<GLint*>(&old_tex));

    glBindTexture(GL_TEXTURE_2D, d_texture);
    err = CGLTexImagePBuffer(CGLGetCurrentContext(), d_pbuffer, GL_FRONT);

    // restore previous texture binding.
    glBindTexture(GL_TEXTURE_2D, old_tex);

    if (err)
        CEGUI_THROW(RendererException(
                        "OpenGLApplePBTextureTarget::declareRenderSize "
                        "- CGLTexImagePBuffer failed: " + String(CGLErrorString(err))));

    // ensure CEGUI::Texture is wrapping real GL texture and has correct size
    d_CEGUITexture->setOpenGLTexture(d_texture, d_area.getSize());
}
NS_IMETHODIMP
nsCanvasRenderingContextGLPrivate::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f)
{
    nsresult rv = NS_OK;

    if (!mGLPbuffer)
        return NS_OK;

    // use GL Drawing if we can get a target GL context; otherwise
    // go through the fallback path.
#ifdef HAVE_GL_DRAWING
    if (mCanvasElement->GLWidgetBeginDrawing()) {
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glClear(GL_COLOR_BUFFER_BIT);

        int bwidth = mGLPbuffer->Width();
        int bheight = mGLPbuffer->Height();

        GLuint tex = 0;
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex);

        CGLError err =
            CGLTexImagePBuffer(CGLGetCurrentContext(),
                               ((nsGLPbufferCGL*)mGLPbuffer)->GetCGLPbuffer(),
                               GL_BACK);
        if (err) {
            fprintf (stderr, "CGLTexImagePBuffer failed: %d\n", err);
            glDeleteTextures(1, &tex);
            return NS_OK;
        }

        glEnable(GL_TEXTURE_RECTANGLE_EXT);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        //glFrustum(-halfWidth, halfWidth, halfHeight, -halfHeight, 1.0, 100000.0);
        glOrtho(0, bwidth, bheight, 0, -0.5, 10.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glBegin(GL_QUADS);

        /* Note that the texture needs a y-flip */
        glTexCoord2f(0.0, bheight);
        glVertex3f(0.0, 0.0, 0.0);

        glTexCoord2f(bwidth, bheight);
        glVertex3f(bwidth, 0.0, 0.0);

        glTexCoord2f(bwidth, 0);
        glVertex3f(bwidth, bheight, 0.0);

        glTexCoord2f(0.0, 0);
        glVertex3f(0.0, bheight, 0.0);

        glEnd();

        glDisable(GL_TEXTURE_RECTANGLE_EXT);
        glDeleteTextures(1, &tex);

        mCanvasElement->GLWidgetSwapBuffers();
        mCanvasElement->GLWidgetEndDrawing();
    } else
#endif
    {
        nsRefPtr<gfxASurface> surf = mGLPbuffer->ThebesSurface();
        if (!surf)
            return NS_OK;

        nsRefPtr<gfxPattern> pat = CanvasGLThebes::CreatePattern(surf);
        gfxMatrix m;
        m.Translate(gfxPoint(0.0, mGLPbuffer->Height()));
        m.Scale(1.0, -1.0);
        pat->SetMatrix(m);

        // XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
        // pixel alignment for this stuff!
        ctx->NewPath();
        ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
        ctx->Fill();
    }
    return rv;
}