VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/presenter/window.cpp@ 53816

Last change on this file since 53816 was 53816, checked in by vboxsync, 10 years ago

3D: scalling factor: separate scaling factors along X and Y axes; move out from atomic variables to read-write semaphores.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 KB
Line 
1/* $Id: window.cpp 53816 2015-01-15 12:01:56Z vboxsync $ */
2
3/** @file
4 * Presenter API: window class implementation.
5 */
6
7/*
8 * Copyright (C) 2014 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.215389.xyz. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "server_presenter.h"
20
21
22CrFbWindow::CrFbWindow(uint64_t parentId) :
23 mSpuWindow(0),
24 mpCompositor(NULL),
25 mcUpdates(0),
26 mxPos(0),
27 myPos(0),
28 mWidth(0),
29 mHeight(0),
30 mParentId(parentId),
31 mScaleFactorWStorage(1.0),
32 mScaleFactorHStorage(1.0)
33{
34 int rc;
35
36 mFlags.Value = 0;
37
38 rc = RTSemRWCreate(&scaleFactorLock);
39 if (!RT_SUCCESS(rc))
40 WARN(("Unable to initialize scaling factor data lock."));
41}
42
43
44bool CrFbWindow::IsCreated() const
45{
46 return !!mSpuWindow;
47}
48
49bool CrFbWindow::IsVisivle() const
50{
51 return mFlags.fVisible;
52}
53
54
55void CrFbWindow::Destroy()
56{
57 CRASSERT(!mcUpdates);
58
59 if (!mSpuWindow)
60 return;
61
62 cr_server.head_spu->dispatch_table.WindowDestroy(mSpuWindow);
63
64 mSpuWindow = 0;
65 mFlags.fDataPresented = 0;
66}
67
68
69int CrFbWindow::Reparent(uint64_t parentId)
70{
71 if (!checkInitedUpdating())
72 {
73 WARN(("err"));
74 return VERR_INVALID_STATE;
75 }
76
77 crDebug("CrFbWindow: reparent to %p (current mxPos=%d, myPos=%d, mWidth=%u, mHeight=%u)",
78 parentId, mxPos, myPos, mWidth, mHeight);
79
80 uint64_t oldParentId = mParentId;
81
82 mParentId = parentId;
83
84 if (mSpuWindow)
85 {
86 if (oldParentId && !parentId && mFlags.fVisible)
87 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, false);
88
89 renderspuSetWindowId(mParentId);
90 renderspuReparentWindow(mSpuWindow);
91 renderspuSetWindowId(cr_server.screen[0].winID);
92
93 if (parentId)
94 {
95 if (mFlags.fVisible)
96 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
97 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, mFlags.fVisible);
98 }
99 }
100
101 return VINF_SUCCESS;
102}
103
104
105int CrFbWindow::SetVisible(bool fVisible)
106{
107 if (!checkInitedUpdating())
108 {
109 WARN(("err"));
110 return VERR_INVALID_STATE;
111 }
112
113 LOG(("CrWIN: Visible [%d]", fVisible));
114
115 if (!fVisible != !mFlags.fVisible)
116 {
117 mFlags.fVisible = fVisible;
118 if (mSpuWindow && mParentId)
119 {
120 if (fVisible)
121 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
122 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, fVisible);
123 }
124 }
125
126 return VINF_SUCCESS;
127}
128
129
130int CrFbWindow::SetSize(uint32_t width, uint32_t height)
131{
132 if (!checkInitedUpdating())
133 {
134 WARN(("err"));
135 return VERR_INVALID_STATE;
136 }
137
138 if (mWidth != width || mHeight != height)
139 {
140 GLdouble scaleFactorW, scaleFactorH;
141
142 /* Reset to default values if operation was unsuccessfull. */
143 if (!GetScaleFactor(&scaleFactorW, &scaleFactorH))
144 scaleFactorW = scaleFactorH = 1.0;
145
146 mFlags.fCompositoEntriesModified = 1;
147 mWidth = scaleFactorW ? (uint32_t)((GLdouble)width * scaleFactorW) : width;
148 mHeight = scaleFactorH ? (uint32_t)((GLdouble)height * scaleFactorH) : height;
149
150 LOG(("CrWIN: Size [%d ; %d]", width, height));
151
152 if (mSpuWindow)
153 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, mWidth, mHeight);
154 }
155
156 return VINF_SUCCESS;
157}
158
159
160int CrFbWindow::SetPosition(int32_t x, int32_t y)
161{
162 if (!checkInitedUpdating())
163 {
164 WARN(("err"));
165 return VERR_INVALID_STATE;
166 }
167
168 LOG(("CrWIN: Pos [%d ; %d]", x, y));
169// always do WindowPosition to ensure window is adjusted properly
170// if (x != mxPos || y != myPos)
171 {
172 mxPos = x;
173 myPos = y;
174 if (mSpuWindow)
175 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, x, y);
176 }
177
178 return VINF_SUCCESS;
179}
180
181
182int CrFbWindow::SetVisibleRegionsChanged()
183{
184 if (!checkInitedUpdating())
185 {
186 WARN(("err"));
187 return VERR_INVALID_STATE;
188 }
189
190 mFlags.fCompositoEntriesModified = 1;
191 return VINF_SUCCESS;
192}
193
194
195int CrFbWindow::SetCompositor(const struct VBOXVR_SCR_COMPOSITOR * pCompositor)
196{
197 if (!checkInitedUpdating())
198 {
199 WARN(("err"));
200 return VERR_INVALID_STATE;
201 }
202
203 mpCompositor = pCompositor;
204 mFlags.fCompositoEntriesModified = 1;
205
206 return VINF_SUCCESS;
207}
208
209
210bool CrFbWindow::SetScaleFactor(GLdouble scaleFactorW, GLdouble scaleFactorH)
211{
212 int rc;
213
214 rc = RTSemRWRequestWrite(scaleFactorLock, RT_INDEFINITE_WAIT);
215 if (RT_SUCCESS(rc))
216 {
217 mScaleFactorWStorage = scaleFactorW;
218 mScaleFactorHStorage = scaleFactorH;
219 RTSemRWReleaseWrite(scaleFactorLock);
220 return true;
221 }
222
223 return false;
224}
225
226
227bool CrFbWindow::GetScaleFactor(GLdouble *scaleFactorW, GLdouble *scaleFactorH)
228{
229 int rc;
230
231 rc = RTSemRWRequestRead(scaleFactorLock, RT_INDEFINITE_WAIT);
232 if (RT_SUCCESS(rc))
233 {
234 *scaleFactorW = mScaleFactorWStorage;
235 *scaleFactorH = mScaleFactorHStorage;
236 RTSemRWReleaseRead(scaleFactorLock);
237 return true;
238 }
239
240 return false;
241}
242
243
244int CrFbWindow::UpdateBegin()
245{
246 ++mcUpdates;
247 if (mcUpdates > 1)
248 return VINF_SUCCESS;
249
250 Assert(!mFlags.fForcePresentOnReenable);
251
252 if (mFlags.fDataPresented)
253 {
254 Assert(mSpuWindow);
255 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, NULL, NULL);
256 mFlags.fForcePresentOnReenable = isPresentNeeded();
257 }
258
259 return VINF_SUCCESS;
260}
261
262
263void CrFbWindow::UpdateEnd()
264{
265 --mcUpdates;
266 Assert(mcUpdates < UINT32_MAX/2);
267 if (mcUpdates)
268 return;
269
270 checkRegions();
271
272 if (mSpuWindow)
273 {
274 bool fPresentNeeded = isPresentNeeded();
275 if (fPresentNeeded || mFlags.fForcePresentOnReenable)
276 {
277 GLdouble scaleFactorW, scaleFactorH;
278 /* Reset to default values if operation was unseccessfull. */
279 if (!GetScaleFactor(&scaleFactorW, &scaleFactorH))
280 scaleFactorW = scaleFactorH = 1.0;
281
282 mFlags.fForcePresentOnReenable = false;
283 if (mpCompositor)
284 {
285 CrVrScrCompositorSetStretching((VBOXVR_SCR_COMPOSITOR *)mpCompositor, scaleFactorW, scaleFactorH);
286 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, mpCompositor, NULL);
287 }
288 else
289 {
290 VBOXVR_SCR_COMPOSITOR TmpCompositor;
291 RTRECT Rect;
292 Rect.xLeft = 0;
293 Rect.yTop = 0;
294 Rect.xRight = mWidth;
295 Rect.yBottom = mHeight;
296 CrVrScrCompositorInit(&TmpCompositor, &Rect);
297 CrVrScrCompositorSetStretching((VBOXVR_SCR_COMPOSITOR *)&TmpCompositor, scaleFactorW, scaleFactorH);
298 /* this is a cleanup operation
299 * empty compositor is guarantid to be released on VBoxPresentComposition return */
300 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, &TmpCompositor, NULL);
301 }
302 g_pLed->Asserted.s.fWriting = 1;
303 }
304
305 /* even if the above branch is entered due to mFlags.fForcePresentOnReenable,
306 * the backend should clean up the compositor as soon as presentation is performed */
307 mFlags.fDataPresented = fPresentNeeded;
308 }
309 else
310 {
311 Assert(!mFlags.fDataPresented);
312 Assert(!mFlags.fForcePresentOnReenable);
313 }
314}
315
316
317uint64_t CrFbWindow::GetParentId()
318{
319 return mParentId;
320}
321
322
323int CrFbWindow::Create()
324{
325 if (mSpuWindow)
326 {
327 //WARN(("window already created"));
328 return VINF_ALREADY_INITIALIZED;
329 }
330
331 CRASSERT(cr_server.fVisualBitsDefault);
332 renderspuSetWindowId(mParentId);
333 mSpuWindow = cr_server.head_spu->dispatch_table.WindowCreate("", cr_server.fVisualBitsDefault);
334 renderspuSetWindowId(cr_server.screen[0].winID);
335 if (mSpuWindow < 0) {
336 WARN(("WindowCreate failed"));
337 return VERR_GENERAL_FAILURE;
338 }
339
340 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, mWidth, mHeight);
341 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
342
343 checkRegions();
344
345 if (mParentId && mFlags.fVisible)
346 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, true);
347
348 return VINF_SUCCESS;
349}
350
351
352CrFbWindow::~CrFbWindow()
353{
354 int rc;
355
356 Destroy();
357
358 rc = RTSemRWDestroy(scaleFactorLock);
359 if (!RT_SUCCESS(rc))
360 WARN(("Unable to release scaling factor data lock."));
361}
362
363
364void CrFbWindow::checkRegions()
365{
366 if (!mSpuWindow)
367 return;
368
369 if (!mFlags.fCompositoEntriesModified)
370 return;
371
372 uint32_t cRects;
373 const RTRECT *pRects;
374 if (mpCompositor)
375 {
376 int rc = CrVrScrCompositorRegionsGet(mpCompositor, &cRects, NULL, &pRects, NULL);
377 if (!RT_SUCCESS(rc))
378 {
379 WARN(("CrVrScrCompositorRegionsGet failed rc %d", rc));
380 cRects = 0;
381 pRects = NULL;
382 }
383 }
384 else
385 {
386 cRects = 0;
387 pRects = NULL;
388 }
389
390 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mSpuWindow, cRects, (const GLint*)pRects);
391
392 mFlags.fCompositoEntriesModified = 0;
393}
394
395
396bool CrFbWindow::isPresentNeeded()
397{
398 return mFlags.fVisible && mWidth && mHeight && mpCompositor && !CrVrScrCompositorIsEmpty(mpCompositor);
399}
400
401
402bool CrFbWindow::checkInitedUpdating()
403{
404 if (!mcUpdates)
405 {
406 WARN(("not updating"));
407 return false;
408 }
409
410 return true;
411}
412
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette