summaryrefslogtreecommitdiffstats
path: root/src/opengl/qgl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/qgl.cpp')
-rw-r--r--src/opengl/qgl.cpp526
1 files changed, 440 insertions, 86 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index cd7a7f0..c0c7781 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -65,15 +65,27 @@
#include "qimage.h"
#include "qgl_p.h"
-#if defined(QT_OPENGL_ES_2)
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
-#else
+#endif
+
+#ifndef QT_OPENGL_ES_2
#include <private/qpaintengine_opengl_p.h>
#endif
+#ifdef Q_WS_QWS
+#include <private/qglpaintdevice_qws_p.h>
+#include <private/qglwindowsurface_qws_p.h>
+#endif
+
+#include <qglpixelbuffer.h>
+#include <qglframebufferobject.h>
+
#include <private/qimage_p.h>
#include <private/qpixmapdata_p.h>
#include <private/qpixmapdata_gl_p.h>
+#include <private/qglpixelbuffer_p.h>
+#include <private/qwindowsurface_gl_p.h>
#include "qcolormap.h"
#include "qcache.h"
#include "qfile.h"
@@ -1290,6 +1302,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
eglContext = 0;
#endif
pbo = 0;
+ fbo = 0;
crWin = false;
initDone = false;
sharing = false;
@@ -1297,6 +1310,8 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
max_texture_size = -1;
version_flags_cached = false;
version_flags = QGLFormat::OpenGL_Version_None;
+ current_fbo = 0;
+ active_engine = 0;
}
QGLContext* QGLContext::currentCtx = 0;
@@ -1307,12 +1322,8 @@ QGLContext* QGLContext::currentCtx = 0;
QGLFramebufferObject::toImage()
*/
-QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
+static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha)
{
- QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
- int w = size.width();
- int h = size.height();
- glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
// OpenGL gives RGBA; Qt wants ARGB
uint *p = (uint*)img.bits();
@@ -1343,7 +1354,30 @@ QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include
}
}
- return img.mirrored();
+ img = img.mirrored();
+}
+
+QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
+{
+ QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
+ int w = size.width();
+ int h = size.height();
+ glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
+ convertFromGLImage(img, w, h, alpha_format, include_alpha);
+ return img;
+}
+
+QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
+{
+ QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
+ int w = size.width();
+ int h = size.height();
+#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ //### glGetTexImage not in GL ES 2.0, need to do something else here!
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
+#endif
+ convertFromGLImage(img, w, h, alpha_format, include_alpha);
+ return img;
}
// returns the highest number closest to v, which is a power of 2
@@ -1429,7 +1463,7 @@ struct DDSFormat {
#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
#endif
-Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg);
+Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg)
Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg()
{
return _qgl_share_reg();
@@ -1546,7 +1580,7 @@ void QGLContextPrivate::cleanup()
Q_Q(QGLContext);
if (pbo) {
QGLContext *ctx = q;
- glDeleteBuffersARB(1, &pbo);
+ glDeleteBuffers(1, &pbo);
pbo = 0;
}
}
@@ -1683,58 +1717,105 @@ static void qt_gl_clean_cache(qint64 cacheKey)
static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum texture_format)
{
- Q_ASSERT(dst.size() == img.size());
Q_ASSERT(dst.depth() == 32);
Q_ASSERT(img.depth() == 32);
- const int width = img.width();
- const int height = img.height();
- const uint *p = (const uint*) img.scanLine(img.height() - 1);
- uint *q = (uint*) dst.scanLine(0);
-
- if (texture_format == GL_BGRA) {
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- // mirror + swizzle
- for (int i=0; i < height; ++i) {
- const uint *end = p + width;
- while (p < end) {
- *q = ((*p << 24) & 0xff000000)
- | ((*p >> 24) & 0x000000ff)
- | ((*p << 8) & 0x00ff0000)
- | ((*p >> 8) & 0x0000ff00);
- p++;
- q++;
+ if (dst.size() != img.size()) {
+ int target_width = dst.width();
+ int target_height = dst.height();
+ qreal sx = target_width / qreal(img.width());
+ qreal sy = target_height / qreal(img.height());
+
+ quint32 *dest = (quint32 *) dst.scanLine(0); // NB! avoid detach here
+ uchar *srcPixels = (uchar *) img.scanLine(img.height() - 1);
+ int sbpl = img.bytesPerLine();
+ int dbpl = dst.bytesPerLine();
+
+ int ix = 0x00010000 / sx;
+ int iy = 0x00010000 / sy;
+
+ quint32 basex = int(0.5 * ix);
+ quint32 srcy = int(0.5 * iy);
+
+ // scale, swizzle and mirror in one loop
+ while (target_height--) {
+ const uint *src = (const quint32 *) (srcPixels - (srcy >> 16) * sbpl);
+ int srcx = basex;
+ for (int x=0; x<target_width; ++x) {
+ uint src_pixel = src[srcx >> 16];
+ if (texture_format == GL_BGRA) {
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ dest[x] = ((src_pixel << 24) & 0xff000000)
+ | ((src_pixel >> 24) & 0x000000ff)
+ | ((src_pixel << 8) & 0x00ff0000)
+ | ((src_pixel >> 8) & 0x0000ff00);
+ } else {
+ dest[x] = src_pixel;
+ }
+ } else { // GL_RGBA
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ dest[x] = (src_pixel << 8) | ((src_pixel >> 24) & 0xff);
+ } else {
+ dest[x] = ((src_pixel << 16) & 0xff0000)
+ | ((src_pixel >> 16) & 0xff)
+ | (src_pixel & 0xff00ff00);
+ }
}
- p -= 2 * width;
- }
- } else {
- const uint bytesPerLine = img.bytesPerLine();
- for (int i=0; i < height; ++i) {
- memcpy(q, p, bytesPerLine);
- q += width;
- p -= width;
+ srcx += ix;
}
+ dest = (quint32 *)(((uchar *) dest) + dbpl);
+ srcy += iy;
}
} else {
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- for (int i=0; i < height; ++i) {
- const uint *end = p + width;
- while (p < end) {
- *q = (*p << 8) | ((*p >> 24) & 0xFF);
- p++;
- q++;
+ const int width = img.width();
+ const int height = img.height();
+ const uint *p = (const uint*) img.scanLine(img.height() - 1);
+ uint *q = (uint*) dst.scanLine(0);
+
+ if (texture_format == GL_BGRA) {
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ // mirror + swizzle
+ for (int i=0; i < height; ++i) {
+ const uint *end = p + width;
+ while (p < end) {
+ *q = ((*p << 24) & 0xff000000)
+ | ((*p >> 24) & 0x000000ff)
+ | ((*p << 8) & 0x00ff0000)
+ | ((*p >> 8) & 0x0000ff00);
+ p++;
+ q++;
+ }
+ p -= 2 * width;
+ }
+ } else {
+ const uint bytesPerLine = img.bytesPerLine();
+ for (int i=0; i < height; ++i) {
+ memcpy(q, p, bytesPerLine);
+ q += width;
+ p -= width;
}
- p -= 2 * width;
}
} else {
- for (int i=0; i < height; ++i) {
- const uint *end = p + width;
- while (p < end) {
- *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
- p++;
- q++;
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ for (int i=0; i < height; ++i) {
+ const uint *end = p + width;
+ while (p < end) {
+ *q = (*p << 8) | ((*p >> 24) & 0xff);
+ p++;
+ q++;
+ }
+ p -= 2 * width;
+ }
+ } else {
+ for (int i=0; i < height; ++i) {
+ const uint *end = p + width;
+ while (p < end) {
+ *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
+ p++;
+ q++;
+ }
+ p -= 2 * width;
}
- p -= 2 * width;
}
}
}
@@ -1764,7 +1845,7 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint
use_pbo = qt_resolve_buffer_extensions(ctx);
if (use_pbo && pbo == 0)
- glGenBuffersARB(1, &pbo);
+ glGenBuffers(1, &pbo);
}
// the GL_BGRA format is only present in GL version >= 1.2
@@ -1777,19 +1858,18 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint
}
// Scale the pixmap if needed. GL textures needs to have the
- // dimensions 2^n+2(border) x 2^m+2(border).
+ // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL
+ // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
int tx_w = qt_next_power_of_two(image.width());
int tx_h = qt_next_power_of_two(image.height());
+ bool scale = false;
- // Note: the clean param is only true when a texture is bound
- // from the QOpenGLPaintEngine - in that case we have to force
- // a premultiplied texture format
QImage img = image;
if (( !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) &&
!(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0) )
&& (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
{
- img = image.scaled(tx_w, tx_h);
+ scale = true;
}
GLuint tx_id;
@@ -1816,28 +1896,35 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint
uchar *ptr = 0;
if (use_pbo) {
- glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
- glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, img.width() * img.height() * 4, 0, GL_STREAM_DRAW_ARB);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, img.width() * img.height() * 4, 0, GL_STREAM_DRAW_ARB);
ptr = reinterpret_cast<uchar *>(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB));
}
- if (ptr) {
- QImage::Format target_format = img.format();
- if (clean || img.format() != QImage::Format_ARGB32)
- target_format = QImage::Format_ARGB32_Premultiplied;
+ QImage::Format target_format = img.format();
+ // Note: the clean param is only true when a texture is bound
+ // from the QOpenGLPaintEngine - in that case we have to force
+ // a premultiplied texture format
+ if (clean || img.format() != QImage::Format_ARGB32)
+ target_format = QImage::Format_ARGB32_Premultiplied;
+ if (img.format() != target_format)
+ img = img.convertToFormat(target_format);
+ if (ptr) {
QImage buffer(ptr, img.width(), img.height(), target_format);
- convertToGLFormatHelper(buffer, img.convertToFormat(target_format), texture_format);
+ convertToGLFormatHelper(buffer, img, texture_format);
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
- glTexImage2D(target, 0, format, img.width(), img.height(), 0, texture_format, GL_UNSIGNED_BYTE, 0);
+ glTexImage2D(target, 0, format, img.width(), img.height(), 0, texture_format,
+ GL_UNSIGNED_BYTE, 0);
} else {
- QImage tx = convertToGLFormat(img, clean, texture_format);
+ QImage tx(scale ? QSize(tx_w, tx_h) : img.size(), target_format);
+ convertToGLFormatHelper(tx, img, texture_format);
glTexImage2D(target, 0, format, tx.width(), tx.height(), 0, texture_format,
GL_UNSIGNED_BYTE, tx.bits());
}
if (use_pbo)
- glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
// this assumes the size of a texture is always smaller than the max cache size
int cost = img.width()*img.height()*4/1024;
@@ -1889,11 +1976,13 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint
/*! \internal */
GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean)
{
-#if !defined(QT_OPENGL_ES_2)
- if (target == qt_gl_preferredTextureTarget() && pixmap.pixmapData()->classId() == QPixmapData::OpenGLClass) {
- const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pixmap.pixmapData());
+ Q_Q(QGLContext);
+ QPixmapData *pd = pixmap.pixmapData();
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) {
+ const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd);
- if (data->isValidContext(QGLContext::currentContext()))
+ if (data->isValidContext(q))
return data->bind();
}
#endif
@@ -2045,12 +2134,34 @@ void QGLContext::deleteTexture(QMacCompatGLuint id)
}
#endif
-// qpaintengine_opengl.cpp
-#if !defined(QT_OPENGL_ES_2)
-extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array);
-#else
-void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) {};
-#endif
+void qt_add_rect_to_array(const QRectF &r, q_vertexType *array)
+{
+ qreal left = r.left();
+ qreal right = r.right();
+ qreal top = r.top();
+ qreal bottom = r.bottom();
+
+ array[0] = f2vt(left);
+ array[1] = f2vt(top);
+ array[2] = f2vt(right);
+ array[3] = f2vt(top);
+ array[4] = f2vt(right);
+ array[5] = f2vt(bottom);
+ array[6] = f2vt(left);
+ array[7] = f2vt(bottom);
+}
+
+void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array)
+{
+ array[0] = f2vt(x1);
+ array[1] = f2vt(y1);
+ array[2] = f2vt(x2);
+ array[3] = f2vt(y1);
+ array[4] = f2vt(x2);
+ array[5] = f2vt(y2);
+ array[6] = f2vt(x1);
+ array[7] = f2vt(y2);
+}
static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget)
{
@@ -2504,7 +2615,7 @@ const QGLContext* QGLContext::currentContext()
*/
/*! \fn int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
-
+
\bold{Win32 only:} This virtual function chooses a pixel format
that matches the OpenGL \link setFormat() format\endlink.
Reimplement this function in a subclass if you need a custom
@@ -2518,7 +2629,7 @@ const QGLContext* QGLContext::currentContext()
*/
/*! \fn void *QGLContext::chooseVisual()
-
+
\bold{X11 only:} This virtual function tries to find a visual that
matches the format, reducing the demands if the original request
cannot be met.
@@ -3237,7 +3348,7 @@ bool QGLWidget::event(QEvent *e)
glFinish();
doneCurrent();
} else if (e->type() == QEvent::ParentChange) {
- if (d->glcx->d_func()->screen != d->xinfo.screen()) {
+ if (d->glcx->d_func()->screen != d->xinfo.screen() || testAttribute(Qt::WA_TranslucentBackground)) {
setContext(new QGLContext(d->glcx->requestedFormat(), this));
// ### recreating the overlay isn't supported atm
}
@@ -4093,14 +4204,16 @@ void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QM
}
#endif
-#if defined(QT_OPENGL_ES_2)
-Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_engine)
-#else
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine)
+#endif
+
+#ifndef QT_OPENGL_ES_2
Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine)
#endif
#ifdef Q_WS_QWS
-Q_OPENGL_EXPORT QOpenGLPaintEngine* qt_qgl_paint_engine()
+Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
{
#if !defined(QT_OPENGL_ES_2)
return qt_gl_engine();
@@ -4118,7 +4231,16 @@ Q_OPENGL_EXPORT QOpenGLPaintEngine* qt_qgl_paint_engine()
*/
QPaintEngine *QGLWidget::paintEngine() const
{
+#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)
return qt_gl_engine();
+#elif defined(QT_OPENGL_ES_2)
+ return qt_gl_2_engine();
+#else
+ if (!qt_gl_preferGL2Engine())
+ return qt_gl_engine();
+ else
+ return qt_gl_2_engine();
+#endif
}
#ifdef QT3_SUPPORT
@@ -4207,6 +4329,8 @@ void QGLExtensions::init_extensions()
glExtensions |= FramebufferObject;
glExtensions |= GenerateMipmap;
#endif
+ if (extensions.contains(QLatin1String("EXT_framebuffer_blit")))
+ glExtensions |= FramebufferBlit;
QGLContext cx(QGLFormat::defaultFormat());
if (glExtensions & TextureCompression) {
@@ -4236,7 +4360,7 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi
}
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
-Q_GLOBAL_STATIC(QString, qt_gl_lib_name);
+Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
{
@@ -4247,7 +4371,7 @@ Q_OPENGL_EXPORT const QString qt_gl_library_name()
{
if (qt_gl_lib_name()->isNull()) {
#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- return QString(QLatin1String("GL"));
+ return QLatin1String("GL");
#else // Q_WS_MAC
return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib");
#endif
@@ -4256,4 +4380,234 @@ Q_OPENGL_EXPORT const QString qt_gl_library_name()
}
#endif
+void QGLDrawable::setDevice(QPaintDevice *pdev)
+{
+ wasBound = false;
+ widget = 0;
+ buffer = 0;
+ fbo = 0;
+#ifdef Q_WS_QWS
+ wsurf = 0;
+#endif
+
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ if (pdev->devType() == QInternal::Pixmap) {
+ QPixmapData *data = static_cast<QPixmap *>(pdev)->pixmapData();
+ Q_ASSERT(data->classId() == QPixmapData::OpenGLClass);
+ pixmapData = static_cast<QGLPixmapData *>(data);
+
+ fbo = pixmapData->fbo();
+ }
+#else
+ Q_ASSERT(pdev->devType() != QInternal::Pixmap);
+#endif
+
+ if (pdev->devType() == QInternal::Widget)
+ widget = static_cast<QGLWidget *>(pdev);
+ else if (pdev->devType() == QInternal::Pbuffer)
+ buffer = static_cast<QGLPixelBuffer *>(pdev);
+ else if (pdev->devType() == QInternal::FramebufferObject)
+ fbo = static_cast<QGLFramebufferObject *>(pdev);
+#ifdef Q_WS_QWS
+ else if (pdev->devType() == QInternal::UnknownDevice)
+ wsurf = static_cast<QWSGLPaintDevice*>(pdev)->windowSurface();
+#elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ else if (pdev->devType() == QInternal::UnknownDevice)
+ wsurf = static_cast<QGLWindowSurface *>(pdev);
+#endif
+}
+
+void QGLDrawable::swapBuffers()
+{
+ if (widget) {
+ if (widget->autoBufferSwap())
+ widget->swapBuffers();
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ } else if (pixmapData) {
+ pixmapData->swapBuffers();
+#endif
+ } else {
+ glFlush();
+ }
+}
+
+void QGLDrawable::makeCurrent()
+{
+ previous_fbo = 0;
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ if (!pixmapData && !fbo) {
+#else
+ if (!fbo) {
+#endif
+ QGLContext *ctx = context();
+ previous_fbo = ctx->d_ptr->current_fbo;
+ ctx->d_ptr->current_fbo = 0;
+ if (previous_fbo)
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ }
+
+ if (widget)
+ widget->makeCurrent();
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ else if (pixmapData)
+ pixmapData->makeCurrent();
+#endif
+ else if (buffer)
+ buffer->makeCurrent();
+#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
+ else if (wsurf)
+ wsurf->context()->makeCurrent();
+#endif
+ else if (fbo) {
+ wasBound = fbo->isBound();
+ if (!wasBound)
+ fbo->bind();
+ }
+}
+
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+QGLPixmapData *QGLDrawable::copyOnBegin() const
+{
+ if (!pixmapData || pixmapData->isUninitialized())
+ return 0;
+ return pixmapData;
+}
+#endif
+
+void QGLDrawable::doneCurrent()
+{
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ if (pixmapData) {
+ pixmapData->doneCurrent();
+ return;
+ }
+#endif
+
+ if (previous_fbo) {
+ QGLContext *ctx = context();
+ ctx->d_ptr->current_fbo = previous_fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, previous_fbo);
+ }
+
+ if (fbo && !wasBound)
+ fbo->release();
+}
+
+QSize QGLDrawable::size() const
+{
+ if (widget) {
+ return QSize(widget->d_func()->glcx->device()->width(),
+ widget->d_func()->glcx->device()->height());
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ } else if (pixmapData) {
+ return pixmapData->size();
+#endif
+ } else if (buffer) {
+ return buffer->size();
+ } else if (fbo) {
+ return fbo->size();
+ }
+#ifdef Q_WS_QWS
+ else if (wsurf)
+ return wsurf->window()->frameSize();
+#elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ else if (wsurf)
+ return QSize(wsurf->width(), wsurf->height());
+#endif
+ return QSize();
+}
+
+QGLFormat QGLDrawable::format() const
+{
+ if (widget)
+ return widget->format();
+ else if (buffer)
+ return buffer->format();
+#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
+ else if (wsurf)
+ return wsurf->context()->format();
+#endif
+ else if (fbo && QGLContext::currentContext()) {
+ QGLFormat fmt = QGLContext::currentContext()->format();
+ fmt.setStencil(fbo->attachment() == QGLFramebufferObject::CombinedDepthStencil);
+ fmt.setDepth(fbo->attachment() != QGLFramebufferObject::NoAttachment);
+ return fmt;
+ }
+
+ return QGLFormat();
+}
+
+GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format)
+{
+ if (widget)
+ return widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true);
+ else if (buffer)
+ return buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true);
+ else if (fbo && QGLContext::currentContext())
+ return const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true);
+#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
+ else if (wsurf)
+ return wsurf->context()->d_func()->bindTexture(image, target, format, true);
+#endif
+ return 0;
+}
+
+GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
+{
+ if (widget)
+ return widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true);
+ else if (buffer)
+ return buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true);
+ else if (fbo && QGLContext::currentContext())
+ return const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true);
+#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
+ else if (wsurf)
+ return wsurf->context()->d_func()->bindTexture(pixmap, target, format, true);
+#endif
+ return 0;
+}
+
+QColor QGLDrawable::backgroundColor() const
+{
+ if (widget)
+ return widget->palette().brush(widget->backgroundRole()).color();
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ else if (pixmapData)
+ return pixmapData->fillColor();
+#endif
+ return QApplication::palette().brush(QPalette::Background).color();
+}
+
+bool QGLDrawable::hasTransparentBackground() const
+{
+ return widget && widget->testAttribute(Qt::WA_TranslucentBackground);
+}
+
+QGLContext *QGLDrawable::context() const
+{
+ if (widget)
+ return widget->d_func()->glcx;
+ else if (buffer)
+ return buffer->d_func()->qctx;
+ else if (fbo)
+ return const_cast<QGLContext *>(QGLContext::currentContext());
+#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
+ else if (wsurf)
+ return wsurf->context();
+#endif
+ return 0;
+}
+
+bool QGLDrawable::autoFillBackground() const
+{
+ if (widget)
+ return widget->autoFillBackground();
+#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
+ else if (pixmapData)
+ return pixmapData->needsFill();
+#endif
+ else
+ return false;
+}
+
QT_END_NAMESPACE