source: trunk/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 8.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the plugins of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "pvreglwindowsurface.h"
43#include "pvreglscreen.h"
44#include <QScreen>
45#include <QDebug>
46#include <QWSDisplay>
47
48PvrEglWindowSurface::PvrEglWindowSurface
49 (QWidget *widget, PvrEglScreen *screen, int screenNum)
50 : QWSGLWindowSurface(widget)
51{
52 setSurfaceFlags(QWSWindowSurface::Opaque);
53
54 this->widget = widget;
55 this->screen = screen;
56 this->pdevice = 0;
57
58 QPoint pos = offset(widget);
59 QSize size = widget->size();
60
61 PvrQwsRect pvrRect;
62 pvrRect.x = pos.x();
63 pvrRect.y = pos.y();
64 pvrRect.width = size.width();
65 pvrRect.height = size.height();
66 transformRects(&pvrRect, 1);
67
68 // Try to recover a previous PvrQwsDrawable object for the widget
69 // if there is one. This can happen when a PvrEglWindowSurface
70 // is created for a widget, bound to a EGLSurface, and then destroyed.
71 // When a new PvrEglWindowSurface is created for the widget, it will
72 // pick up the previous PvrQwsDrawable if the EGLSurface has not been
73 // destroyed in the meantime.
74 drawable = pvrQwsFetchWindow((long)widget);
75 if (drawable)
76 pvrQwsSetGeometry(drawable, &pvrRect);
77 else
78 drawable = pvrQwsCreateWindow(screenNum, (long)widget, &pvrRect);
79 pvrQwsSetRotation(drawable, screen->transformation());
80}
81
82PvrEglWindowSurface::PvrEglWindowSurface()
83 : QWSGLWindowSurface()
84{
85 setSurfaceFlags(QWSWindowSurface::Opaque);
86 drawable = 0;
87 widget = 0;
88 screen = 0;
89 pdevice = 0;
90}
91
92PvrEglWindowSurface::~PvrEglWindowSurface()
93{
94 // Release the PvrQwsDrawable. If it is bound to an EGLSurface,
95 // then it will stay around until a new PvrEglWindowSurface is
96 // created for the widget. If it is not bound to an EGLSurface,
97 // it will be destroyed immediately.
98 if (drawable && pvrQwsReleaseWindow(drawable))
99 pvrQwsDestroyDrawable(drawable);
100
101 delete pdevice;
102}
103
104bool PvrEglWindowSurface::isValid() const
105{
106 return (widget != 0);
107}
108
109void PvrEglWindowSurface::setGeometry(const QRect &rect)
110{
111 if (drawable) {
112 // XXX: adjust for the screen offset.
113 PvrQwsRect pvrRect;
114 pvrRect.x = rect.x();
115 pvrRect.y = rect.y();
116 pvrRect.width = rect.width();
117 pvrRect.height = rect.height();
118 transformRects(&pvrRect, 1);
119 pvrQwsSetGeometry(drawable, &pvrRect);
120 pvrQwsSetRotation(drawable, screen->transformation());
121 }
122 QWSGLWindowSurface::setGeometry(rect);
123}
124
125bool PvrEglWindowSurface::move(const QPoint &offset)
126{
127 QRect rect = geometry().translated(offset);
128 if (drawable) {
129 PvrQwsRect pvrRect;
130 pvrRect.x = rect.x();
131 pvrRect.y = rect.y();
132 pvrRect.width = rect.width();
133 pvrRect.height = rect.height();
134 transformRects(&pvrRect, 1);
135 pvrQwsSetGeometry(drawable, &pvrRect);
136 pvrQwsSetRotation(drawable, screen->transformation());
137 }
138 return QWSGLWindowSurface::move(offset);
139}
140
141QByteArray PvrEglWindowSurface::permanentState() const
142{
143 // Nothing interesting to pass to the server just yet.
144 return QByteArray();
145}
146
147void PvrEglWindowSurface::setPermanentState(const QByteArray &state)
148{
149 Q_UNUSED(state);
150}
151
152void PvrEglWindowSurface::flush
153 (QWidget *widget, const QRegion &region, const QPoint &offset)
154{
155 // The GL paint engine is responsible for the swapBuffers() call.
156 // If we were to call the base class's implementation of flush()
157 // then it would fetch the image() and manually blit it to the
158 // screeen instead of using the fast PVR2D blit.
159 Q_UNUSED(widget);
160 Q_UNUSED(region);
161 Q_UNUSED(offset);
162}
163
164QImage PvrEglWindowSurface::image() const
165{
166 if (drawable) {
167 PvrQwsRect pvrRect;
168 pvrQwsGetGeometry(drawable, &pvrRect);
169 void *data = pvrQwsGetRenderBuffer(drawable);
170 if (data) {
171 return QImage((uchar *)data, pvrRect.width, pvrRect.height,
172 pvrQwsGetStride(drawable), screen->pixelFormat());
173 }
174 }
175 return QImage(16, 16, screen->pixelFormat());
176}
177
178QPaintDevice *PvrEglWindowSurface::paintDevice()
179{
180 return widget;
181}
182
183void PvrEglWindowSurface::setDirectRegion(const QRegion &r, int id)
184{
185 QWSGLWindowSurface::setDirectRegion(r, id);
186
187 if (!drawable)
188 return;
189
190 // Clip the region to the window boundaries in case the child
191 // is partially outside the geometry of the parent.
192 QWidget *window = widget->window();
193 QRegion region = r;
194 if (widget != window) {
195 QRect rect = window->geometry();
196 rect.moveTo(window->mapToGlobal(QPoint(0, 0)));
197 region = region.intersect(rect);
198 }
199
200 if (region.isEmpty()) {
201 pvrQwsClearVisibleRegion(drawable);
202 } else if (region.rectCount() == 1) {
203 QRect rect = region.boundingRect();
204 PvrQwsRect pvrRect;
205 pvrRect.x = rect.x();
206 pvrRect.y = rect.y();
207 pvrRect.width = rect.width();
208 pvrRect.height = rect.height();
209 transformRects(&pvrRect, 1);
210 pvrQwsSetVisibleRegion(drawable, &pvrRect, 1);
211 pvrQwsSetRotation(drawable, screen->transformation());
212 if (!pvrQwsSwapBuffers(drawable, 1))
213 screen->solidFill(QColor(0, 0, 0), region);
214 } else {
215 QVector<QRect> rects = region.rects();
216 PvrQwsRect *pvrRects = new PvrQwsRect [rects.size()];
217 for (int index = 0; index < rects.size(); ++index) {
218 QRect rect = rects[index];
219 pvrRects[index].x = rect.x();
220 pvrRects[index].y = rect.y();
221 pvrRects[index].width = rect.width();
222 pvrRects[index].height = rect.height();
223 }
224 transformRects(pvrRects, rects.size());
225 pvrQwsSetVisibleRegion(drawable, pvrRects, rects.size());
226 pvrQwsSetRotation(drawable, screen->transformation());
227 if (!pvrQwsSwapBuffers(drawable, 1))
228 screen->solidFill(QColor(0, 0, 0), region);
229 delete [] pvrRects;
230 }
231}
232
233void PvrEglWindowSurface::transformRects(PvrQwsRect *rects, int count) const
234{
235 switch (screen->transformation()) {
236 case 0: break;
237
238 case 90:
239 {
240 for (int index = 0; index < count; ++index) {
241 int x = rects[index].y;
242 int y = screen->height() - (rects[index].x + rects[index].width);
243 rects[index].x = x;
244 rects[index].y = y;
245 qSwap(rects[index].width, rects[index].height);
246 }
247 }
248 break;
249
250 case 180:
251 {
252 for (int index = 0; index < count; ++index) {
253 int x = screen->width() - (rects[index].x + rects[index].width);
254 int y = screen->height() - (rects[index].y + rects[index].height);
255 rects[index].x = x;
256 rects[index].y = y;
257 }
258 }
259 break;
260
261 case 270:
262 {
263 for (int index = 0; index < count; ++index) {
264 int x = screen->width() - (rects[index].y + rects[index].height);
265 int y = rects[index].x;
266 rects[index].x = x;
267 rects[index].y = y;
268 qSwap(rects[index].width, rects[index].height);
269 }
270 }
271 break;
272 }
273}
Note: See TracBrowser for help on using the repository browser.