am 2257c1fd: am 3127d80b: Merge "opengles emulator: handle window surface resize"

* commit '2257c1fd9f7f9d057bdc811208e342483c59c935':
  opengles emulator: handle window surface resize
This commit is contained in:
David Turner
2011-08-10 01:46:49 -07:00
committed by Android Git Automerger
2 changed files with 105 additions and 28 deletions

View File

@@ -34,6 +34,8 @@ WindowSurface::WindowSurface() :
m_drawContext(NULL),
m_width(0),
m_height(0),
m_pbufWidth(0),
m_pbufHeight(0),
m_useEGLImage(false),
m_useBindToTexture(false)
{
@@ -56,6 +58,7 @@ WindowSurface *WindowSurface::create(int p_config, int p_width, int p_height)
if (!win) {
return NULL;
}
win->m_fbconf = fbconf;
FrameBuffer *fb = FrameBuffer::getFB();
const FrameBufferCaps &caps = fb->getCaps();
@@ -79,34 +82,7 @@ WindowSurface *WindowSurface::create(int p_config, int p_width, int p_height)
if (win->m_useEGLImage) {
}
else if (0 != (fbconf->getSurfaceType() & EGL_PBUFFER_BIT)) {
//
// Use Pbuffer for the rendering surface, if possible
// set it such that it will be able to be bound to a texture
// later to prevent readback.
//
EGLint pbufAttribs[12];
pbufAttribs[0] = EGL_WIDTH;
pbufAttribs[1] = p_width;
pbufAttribs[2] = EGL_HEIGHT;
pbufAttribs[3] = p_height;
if (caps.has_BindToTexture) {
pbufAttribs[4] = EGL_TEXTURE_FORMAT;
pbufAttribs[5] = EGL_TEXTURE_RGBA;
pbufAttribs[6] = EGL_TEXTURE_TARGET;
pbufAttribs[7] = EGL_TEXTURE_2D;
pbufAttribs[8] = EGL_NONE;
win->m_useBindToTexture = true;
}
else {
pbufAttribs[4] = EGL_NONE;
}
win->m_eglSurface = s_egl.eglCreatePbufferSurface(fb->getDisplay(),
fbconf->getEGLConfig(),
pbufAttribs);
if (win->m_eglSurface == EGL_NO_SURFACE) {
if (!win->resizePbuffer(p_width, p_height)) {
delete win;
return NULL;
}
@@ -156,6 +132,24 @@ void WindowSurface::flushColorBuffer()
void WindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer)
{
m_attachedColorBuffer = p_colorBuffer;
//
// resize the window if the attached color buffer is of different
// size
//
unsigned int cbWidth = m_attachedColorBuffer->getWidth();
unsigned int cbHeight = m_attachedColorBuffer->getHeight();
if (cbWidth != m_width || cbHeight != m_height) {
if (m_pbufWidth && m_pbufHeight) {
// if we use pbuffer, need to resize it
resizePbuffer(cbWidth, cbHeight);
}
m_width = cbWidth;
m_height = cbHeight;
}
}
//
@@ -262,3 +256,81 @@ void WindowSurface::copyToColorBuffer()
prevReadSurf, prevContext);
}
bool WindowSurface::resizePbuffer(unsigned int p_width, unsigned int p_height)
{
if (m_eglSurface &&
m_pbufWidth == p_width &&
m_pbufHeight == p_height) {
// no need to resize
return true;
}
FrameBuffer *fb = FrameBuffer::getFB();
EGLContext prevContext = s_egl.eglGetCurrentContext();
EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
EGLSurface prevPbuf = m_eglSurface;
bool needRebindContext = m_eglSurface &&
(prevReadSurf == m_eglSurface ||
prevDrawSurf == m_eglSurface);
if (needRebindContext) {
s_egl.eglMakeCurrent(fb->getDisplay(), EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
//
// Destroy previous surface
//
if (m_eglSurface) {
s_egl.eglDestroySurface(fb->getDisplay(), m_eglSurface);
m_eglSurface = NULL;
}
const FrameBufferCaps &caps = fb->getCaps();
//
// Create pbuffer surface, if possible
// set it such that it will be able to be bound to a texture
// later to prevent readback.
//
EGLint pbufAttribs[12];
pbufAttribs[0] = EGL_WIDTH;
pbufAttribs[1] = p_width;
pbufAttribs[2] = EGL_HEIGHT;
pbufAttribs[3] = p_height;
if (caps.has_BindToTexture) {
pbufAttribs[4] = EGL_TEXTURE_FORMAT;
pbufAttribs[5] = EGL_TEXTURE_RGBA;
pbufAttribs[6] = EGL_TEXTURE_TARGET;
pbufAttribs[7] = EGL_TEXTURE_2D;
pbufAttribs[8] = EGL_NONE;
m_useBindToTexture = true;
}
else {
pbufAttribs[4] = EGL_NONE;
}
m_eglSurface = s_egl.eglCreatePbufferSurface(fb->getDisplay(),
m_fbconf->getEGLConfig(),
pbufAttribs);
if (m_eglSurface == EGL_NO_SURFACE) {
fprintf(stderr, "Renderer error: failed to create/resize pbuffer!!\n");
return false;
}
m_pbufWidth = p_width;
m_pbufHeight = p_height;
if (needRebindContext) {
s_egl.eglMakeCurrent(fb->getDisplay(),
(prevDrawSurf==prevPbuf) ? m_eglSurface : prevDrawSurf,
(prevReadSurf==prevPbuf) ? m_eglSurface : prevReadSurf,
prevContext);
}
return true;
}

View File

@@ -18,6 +18,7 @@
#include "ColorBuffer.h"
#include "RenderContext.h"
#include "FBConfig.h"
#include "SmartPtr.h"
#include "FixedBuffer.h"
#include <EGL/egl.h>
@@ -44,6 +45,7 @@ private:
WindowSurface();
void copyToColorBuffer(); // copy pbuffer content with readback+download
bool resizePbuffer(unsigned int p_width, unsigned int p_height);
private:
GLuint m_fbObj; // GLES Framebuffer object (when EGLimage is used)
@@ -55,10 +57,13 @@ private:
RenderContextPtr m_drawContext;
GLuint m_width;
GLuint m_height;
GLuint m_pbufWidth;
GLuint m_pbufHeight;
bool m_useEGLImage;
bool m_useBindToTexture;
FixedBuffer m_xferBuffer;
FixedBuffer m_xUpdateBuf;
const FBConfig *m_fbconf;
};
typedef SmartPtr<WindowSurface> WindowSurfacePtr;