summaryrefslogtreecommitdiffstats
path: root/examples/qws/ahigl/qwindowsurface_ahigl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/qws/ahigl/qwindowsurface_ahigl.cpp')
-rw-r--r--examples/qws/ahigl/qwindowsurface_ahigl.cpp349
1 files changed, 349 insertions, 0 deletions
diff --git a/examples/qws/ahigl/qwindowsurface_ahigl.cpp b/examples/qws/ahigl/qwindowsurface_ahigl.cpp
new file mode 100644
index 0000000..79924f9
--- /dev/null
+++ b/examples/qws/ahigl/qwindowsurface_ahigl.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsurface_ahigl_p.h"
+#include "qscreenahigl_qws.h"
+
+#include <qwsdisplay_qws.h>
+#include <QtGui/QPaintDevice>
+#include <QtGui/QWidget>
+#include <QtOpenGL/private/qglpaintdevice_qws_p.h>
+#include <QtOpenGL/private/qgl_p.h>
+#include <GLES/gl.h>
+
+/*!
+ \class QAhiGLWindowSurfacePrivate
+ \internal
+
+ \brief The QAhiGLWindowSurfacePrivate class is the private implementation
+ class for class QAhiGLWindowSurface.
+
+ This class contains only state variables.
+ */
+//! [0]
+class QAhiGLWindowSurfacePrivate
+{
+public:
+ QAhiGLWindowSurfacePrivate(EGLDisplay eglDisplay,
+ EGLSurface eglSurface,
+ EGLContext eglContext);
+
+ QPaintDevice *device;
+
+ int textureWidth;
+ int textureHeight;
+
+ GLuint texture;
+ GLuint frameBufferObject;
+ GLuint depthbuf;
+
+ EGLDisplay display;
+ EGLSurface surface;
+ EGLContext context;
+};
+//! [0]
+
+/*!
+ The construct just sets statwe variables using the ones
+ provided.
+ */
+QAhiGLWindowSurfacePrivate::QAhiGLWindowSurfacePrivate(EGLDisplay eglDisplay,
+ EGLSurface eglSurface,
+ EGLContext eglContext)
+ : texture(0), frameBufferObject(0), depthbuf(0), display(eglDisplay),
+ surface(eglSurface), context(eglContext)
+{
+}
+
+inline static int nextPowerOfTwo(uint v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ ++v;
+ return v;
+}
+
+/*!
+ \class QAhiGLWindowSurface
+ \preliminary
+ \internal
+
+ \brief The QAhiGLWindowSurface class provides the drawing area
+ for top-level windows using OpenGL for drawing on an ATI handheld
+ device.
+
+ In \l{Qt for Embedded Linux}, the default behavior for each client is to
+ render widgets into an area of memory. The server then displays
+ the contents of that memory on the screen. For ATI handheld
+ devices using OpenGL, QAhiGLWindowSurface is the window surface
+ class that allocates and manages the memory areas in the clients
+ and the server.
+
+ When a screen update is required, the server runs through all the
+ top-level windows that intersect with the region being updated,
+ ensuring that the clients have updated their window surfaces. Then
+ the server uses the screen driver to copy the contents of the
+ affected window surfaces into its composition and then display the
+ composition on the screen.
+
+ \tableofcontents
+
+ \section1 Pure Virtual Functions
+
+ There are two window surface instances for each top-level window.
+ One is used by the application when drawing a window, and the
+ other is used by the server application to make its copy for
+ building a window composition to send to the screen.
+
+ The key() function is implemented to uniquely identify this window
+ surface class as "ahigl", and the isValid() function is
+ implemented to determine whether the associated window is still
+ acceptable for representation by this window surface class. It
+ must either be a window using an \l {QGLWidget} {OpenGL widget},
+ or it must be a window whose frame is no bigger than 256 x 256.
+
+ The setGeometry() function is implemented to change the geometry
+ of the frame buffer whenever the geometry of the associated
+ top-level window changes. The image() function is called by the
+ window system when building window compositions to return an image
+ of the top-level window.
+
+ The paintDevice() function is implemented to return the appropriate
+ paint device.
+
+ \section1 Virtual Functions
+
+ When painting onto the surface, the window system will always call
+ the beginPaint() function before any painting operations are
+ performed. It ensures that the correct frame buffer will be used
+ by the OpenGL library for painting operations. Likewise, the
+ endPaint() function is automatically called when the painting is
+ done, but it isn't implemented for this example.
+*/
+
+/*!
+ This is the client side constructor.
+ */
+//! [1]
+QAhiGLWindowSurface::QAhiGLWindowSurface(QWidget *widget,
+ EGLDisplay eglDisplay,
+ EGLSurface eglSurface,
+ EGLContext eglContext)
+ : QWSGLWindowSurface(widget)
+{
+ d_ptr = new QAhiGLWindowSurfacePrivate(eglDisplay, eglSurface, eglContext);
+ d_ptr->device = new QWSGLPaintDevice(widget);
+
+ setSurfaceFlags(QWSWindowSurface::Buffered);
+}
+//! [1]
+
+/*!
+ This is the server side constructor.
+ */
+//! [2]
+QAhiGLWindowSurface::QAhiGLWindowSurface(EGLDisplay eglDisplay,
+ EGLSurface eglSurface,
+ EGLContext eglContext)
+{
+ d_ptr = new QAhiGLWindowSurfacePrivate(eglDisplay, eglSurface, eglContext);
+ setSurfaceFlags(QWSWindowSurface::Buffered);
+}
+//! [2]
+
+/*!
+ The destructor deletes the OpenGL structures held by the
+ private implementation class, and then it deletes the
+ private implementation class.
+ */
+QAhiGLWindowSurface::~QAhiGLWindowSurface()
+{
+ if (d_ptr->texture)
+ glDeleteTextures(1, &d_ptr->texture);
+ if (d_ptr->depthbuf)
+ glDeleteRenderbuffersOES(1, &d_ptr->depthbuf);
+ if (d_ptr->frameBufferObject)
+ glDeleteFramebuffersOES(1, &d_ptr->frameBufferObject);
+
+ delete d_ptr;
+}
+
+/*!
+ This function changes the geometry of the frame buffer
+ to the geometry in \a rect. It is called whenever the
+ geometry of the associated top-level window changes. It
+ also rebuilds the window surface's texture and binds
+ the OpenGL identifier to the texture for use by the
+ OpenGL library.
+ */
+//! [3]
+void QAhiGLWindowSurface::setGeometry(const QRect &rect)
+{
+ QSize size = rect.size();
+
+ const QWidget *w = window();
+ if (w && !w->mask().isEmpty()) {
+ const QRegion region = w->mask()
+ & rect.translated(-w->geometry().topLeft());
+ size = region.boundingRect().size();
+ }
+
+ if (geometry().size() != size) {
+
+ // Driver specific limitations:
+ // FBO maximimum size of 256x256
+ // Depth buffer required
+
+ d_ptr->textureWidth = qMin(256, nextPowerOfTwo(size.width()));
+ d_ptr->textureHeight = qMin(256, nextPowerOfTwo(size.height()));
+
+ glGenTextures(1, &d_ptr->texture);
+ glBindTexture(GL_TEXTURE_2D, d_ptr->texture);
+
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ const int bufSize = d_ptr->textureWidth * d_ptr->textureHeight * 2;
+ GLshort buf[bufSize];
+ memset(buf, 0, sizeof(GLshort) * bufSize);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d_ptr->textureWidth,
+ d_ptr->textureHeight, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, buf);
+
+ glGenRenderbuffersOES(1, &d_ptr->depthbuf);
+ glBindRenderbufferOES(GL_RENDERBUFFER_EXT, d_ptr->depthbuf);
+ glRenderbufferStorageOES(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16,
+ d_ptr->textureWidth, d_ptr->textureHeight);
+
+ glGenFramebuffersOES(1, &d_ptr->frameBufferObject);
+ glBindFramebufferOES(GL_FRAMEBUFFER_EXT, d_ptr->frameBufferObject);
+
+ glFramebufferTexture2DOES(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, d_ptr->texture, 0);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_EXT,
+ GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT, d_ptr->depthbuf);
+ glBindFramebufferOES(GL_FRAMEBUFFER_EXT, 0);
+ }
+
+ QWSGLWindowSurface::setGeometry(rect);
+}
+//! [3]
+
+/*!
+ Returns the window surface's texture as a QByteArray.
+ */
+QByteArray QAhiGLWindowSurface::permanentState() const
+{
+ QByteArray array;
+ array.resize(sizeof(GLuint));
+
+ char *ptr = array.data();
+ reinterpret_cast<GLuint*>(ptr)[0] = textureId();
+ return array;
+}
+
+/*!
+ Sets the window surface's texture to \a data.
+ */
+void QAhiGLWindowSurface::setPermanentState(const QByteArray &data)
+{
+ const char *ptr = data.constData();
+ d_ptr->texture = reinterpret_cast<const GLuint*>(ptr)[0];
+}
+
+/*!
+ Returns the paint device being used for this window surface.
+ */
+QPaintDevice *QAhiGLWindowSurface::paintDevice()
+{
+ return d_ptr->device;
+}
+
+/*!
+ Returns the window surface's texture.
+ */
+GLuint QAhiGLWindowSurface::textureId() const
+{
+ return d_ptr->texture;
+}
+
+/*!
+ The \l {QWSServer} {window system} always calls this function
+ before any painting operations begin for this window surface.
+ It ensures that the correct frame buffer will be used by the
+ OpenGL library for painting operations.
+ */
+//! [4]
+void QAhiGLWindowSurface::beginPaint(const QRegion &region)
+{
+ QWSGLWindowSurface::beginPaint(region);
+
+ if (d_ptr->frameBufferObject)
+ glBindFramebufferOES(GL_FRAMEBUFFER_EXT, d_ptr->frameBufferObject);
+}
+//! [4]
+
+/*!
+ This function returns true if the window associated with
+ this window surface can still rendered using this window
+ surface class. Either the window's top-level widget must
+ be an \l {QGLWidget} {OpenGL widget}, or the window's
+ frame must be no bigger than 256 x 256.
+ */
+//! [5]
+bool QAhiGLWindowSurface::isValid() const
+{
+ if (!qobject_cast<QGLWidget*>(window())) {
+ const QRect r = window()->frameGeometry();
+ if (r.width() > 256 || r.height() > 256)
+ return false;
+ }
+ return true;
+}
+//! [5]