VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/presenter/display_window.cpp@ 69500

Last change on this file since 69500 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.7 KB
Line 
1/* $Id: display_window.cpp 69500 2017-10-28 15:14:05Z vboxsync $ */
2
3/** @file
4 * Presenter API: CrFbDisplayWindow class implementation -- display content into host GUI window.
5 */
6
7/*
8 * Copyright (C) 2014-2017 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. 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
21CrFbDisplayWindow::CrFbDisplayWindow(const RTRECT *pViewportRect, uint64_t parentId) :
22 mpWindow(NULL),
23 mViewportRect(*pViewportRect),
24 mu32Screen(~0),
25 mParentId(parentId)
26{
27 mFlags.u32Value = 0;
28}
29
30
31CrFbDisplayWindow::~CrFbDisplayWindow()
32{
33 if (mpWindow)
34 delete mpWindow;
35}
36
37
38int CrFbDisplayWindow::UpdateBegin(struct CR_FRAMEBUFFER *pFb)
39{
40 int rc = mpWindow ? mpWindow->UpdateBegin() : VINF_SUCCESS;
41 if (RT_SUCCESS(rc))
42 {
43 rc = CrFbDisplayBase::UpdateBegin(pFb);
44 if (RT_SUCCESS(rc))
45 return VINF_SUCCESS;
46 else
47 {
48 WARN(("err"));
49 if (mpWindow)
50 mpWindow->UpdateEnd();
51 }
52 }
53 else
54 WARN(("err"));
55
56 return rc;
57}
58
59
60void CrFbDisplayWindow::UpdateEnd(struct CR_FRAMEBUFFER *pFb)
61{
62 CrFbDisplayBase::UpdateEnd(pFb);
63
64 if (mpWindow)
65 mpWindow->UpdateEnd();
66}
67
68
69int CrFbDisplayWindow::RegionsChanged(struct CR_FRAMEBUFFER *pFb)
70{
71 int rc = CrFbDisplayBase::RegionsChanged(pFb);
72 if (!RT_SUCCESS(rc))
73 {
74 WARN(("err"));
75 return rc;
76 }
77
78 if (mpWindow && mpWindow->GetParentId())
79 {
80 rc = mpWindow->Create();
81 if (!RT_SUCCESS(rc))
82 {
83 WARN(("err"));
84 return rc;
85 }
86 }
87
88 return VINF_SUCCESS;
89}
90
91
92int CrFbDisplayWindow::EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
93{
94 int rc = CrFbDisplayBase::EntryCreated(pFb, hEntry);
95 if (!RT_SUCCESS(rc))
96 {
97 WARN(("err"));
98 return rc;
99 }
100
101 if (mpWindow && mpWindow->GetParentId())
102 {
103 rc = mpWindow->Create();
104 if (!RT_SUCCESS(rc))
105 {
106 WARN(("err"));
107 return rc;
108 }
109 }
110
111 return VINF_SUCCESS;
112}
113
114
115int CrFbDisplayWindow::EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
116{
117 int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry);
118 if (!RT_SUCCESS(rc))
119 {
120 WARN(("err"));
121 return rc;
122 }
123
124 if (mpWindow && mpWindow->GetParentId())
125 {
126 rc = mpWindow->Create();
127 if (!RT_SUCCESS(rc))
128 {
129 WARN(("err"));
130 return rc;
131 }
132 }
133
134 return VINF_SUCCESS;
135}
136
137
138int CrFbDisplayWindow::EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
139{
140 int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry);
141 if (!RT_SUCCESS(rc))
142 {
143 WARN(("err"));
144 return rc;
145 }
146
147 if (mpWindow && mpWindow->GetParentId())
148 {
149 rc = mpWindow->Create();
150 if (!RT_SUCCESS(rc))
151 {
152 WARN(("err"));
153 return rc;
154 }
155 }
156
157 return VINF_SUCCESS;
158}
159
160
161int CrFbDisplayWindow::FramebufferChanged(struct CR_FRAMEBUFFER *pFb)
162{
163 int rc = CrFbDisplayBase::FramebufferChanged(pFb);
164 if (!RT_SUCCESS(rc))
165 {
166 WARN(("err"));
167 return rc;
168 }
169
170 return screenChanged();
171}
172
173
174const RTRECT* CrFbDisplayWindow::getViewportRect()
175{
176 return &mViewportRect;
177}
178
179
180int CrFbDisplayWindow::setViewportRect(const RTRECT *pViewportRect)
181{
182 if (!isUpdating())
183 {
184 WARN(("not updating!"));
185 return VERR_INVALID_STATE;
186 }
187
188 // always call SetPosition to ensure window is adjustep properly
189 // if (pViewportRect->xLeft != mViewportRect.xLeft || pViewportRect->yTop != mViewportRect.yTop)
190 if (mpWindow)
191 {
192 const RTRECT* pRect = getRect();
193 int rc = mpWindow->SetPosition(pRect->xLeft - pViewportRect->xLeft, pRect->yTop - pViewportRect->yTop);
194 if (!RT_SUCCESS(rc))
195 {
196 WARN(("SetPosition failed"));
197 return rc;
198 }
199 }
200
201 mViewportRect = *pViewportRect;
202
203 return VINF_SUCCESS;
204}
205
206
207CrFbWindow * CrFbDisplayWindow::windowDetach(bool fCleanup)
208{
209 if (isUpdating())
210 {
211 WARN(("updating!"));
212 return NULL;
213 }
214
215 CrFbWindow * pWindow = mpWindow;
216 if (mpWindow)
217 {
218 if (fCleanup)
219 windowCleanup();
220 mpWindow = NULL;
221 }
222 return pWindow;
223}
224
225
226CrFbWindow * CrFbDisplayWindow::windowAttach(CrFbWindow * pNewWindow)
227{
228 if (isUpdating())
229 {
230 WARN(("updating!"));
231 return NULL;
232 }
233
234 CrFbWindow * pOld = mpWindow;
235 if (mpWindow)
236 windowDetach();
237
238 mpWindow = pNewWindow;
239 if (pNewWindow)
240 windowSync();
241
242 return mpWindow;
243}
244
245
246int CrFbDisplayWindow::reparent(uint64_t parentId)
247{
248 if (!isUpdating())
249 {
250 WARN(("not updating!"));
251 return VERR_INVALID_STATE;
252 }
253
254 crDebug("CrFbDisplayWindow: change parent from %p to %p.", mParentId, parentId);
255
256 mParentId = parentId;
257 int rc = VINF_SUCCESS;
258
259 /* Force notify Render SPU about parent window ID change in order to prevent
260 * crashes when it tries to access already deallocated parent window.
261 * Previously, we also used isActive() here, however it might become FALSE for the case
262 * when VM Window goes fullscreen mode and back. */
263 if ( /* isActive() && */ mpWindow)
264 {
265 rc = mpWindow->Reparent(parentId);
266 if (!RT_SUCCESS(rc))
267 WARN(("window reparent failed"));
268
269 mFlags.fNeForce = 1;
270 }
271
272 return rc;
273}
274
275
276bool CrFbDisplayWindow::isVisible()
277{
278 HCR_FRAMEBUFFER hFb = getFramebuffer();
279 if (!hFb)
280 return false;
281 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(hFb);
282 return !CrVrScrCompositorIsEmpty(pCompositor);
283}
284
285
286int CrFbDisplayWindow::winVisibilityChanged()
287{
288 HCR_FRAMEBUFFER hFb = getFramebuffer();
289 if (!hFb || !CrFbIsEnabled(hFb))
290 {
291 Assert(!mpWindow || !mpWindow->IsVisivle());
292 return VINF_SUCCESS;
293 }
294
295 int rc = VINF_SUCCESS;
296
297 if (mpWindow)
298 {
299 rc = mpWindow->UpdateBegin();
300 if (RT_SUCCESS(rc))
301 {
302 rc = mpWindow->SetVisible(!g_CrPresenter.fWindowsForceHidden);
303 if (!RT_SUCCESS(rc))
304 WARN(("SetVisible failed, rc %d", rc));
305
306 mpWindow->UpdateEnd();
307 }
308 else
309 WARN(("UpdateBegin failed, rc %d", rc));
310 }
311
312 return rc;
313}
314
315
316CrFbWindow* CrFbDisplayWindow::getWindow()
317{
318 return mpWindow;
319}
320
321
322void CrFbDisplayWindow::onUpdateEnd()
323{
324 CrFbDisplayBase::onUpdateEnd();
325 bool fVisible = isVisible();
326 if (mFlags.fNeVisible != fVisible || mFlags.fNeForce)
327 {
328 crVBoxServerNotifyEvent(mu32Screen,
329 fVisible? VBOX3D_NOTIFY_EVENT_TYPE_3DDATA_VISIBLE:
330 VBOX3D_NOTIFY_EVENT_TYPE_3DDATA_HIDDEN,
331 NULL, 0);
332 mFlags.fNeVisible = fVisible;
333 mFlags.fNeForce = 0;
334 }
335}
336
337
338void CrFbDisplayWindow::ueRegions()
339{
340 if (mpWindow)
341 mpWindow->SetVisibleRegionsChanged();
342}
343
344
345int CrFbDisplayWindow::screenChanged()
346{
347 if (!isUpdating())
348 {
349 WARN(("not updating!"));
350 return VERR_INVALID_STATE;
351 }
352
353 int rc = windowDimensionsSync();
354 if (!RT_SUCCESS(rc))
355 {
356 WARN(("windowDimensionsSync failed rc %d", rc));
357 return rc;
358 }
359
360 return VINF_SUCCESS;
361}
362
363
364int CrFbDisplayWindow::windowSetCompositor(bool fSet)
365{
366 if (!mpWindow)
367 return VINF_SUCCESS;
368
369 if (fSet)
370 {
371 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(getFramebuffer());
372 return mpWindow->SetCompositor(pCompositor);
373 }
374 return mpWindow->SetCompositor(NULL);
375}
376
377
378int CrFbDisplayWindow::windowCleanup()
379{
380 if (!mpWindow)
381 return VINF_SUCCESS;
382
383 int rc = mpWindow->UpdateBegin();
384 if (!RT_SUCCESS(rc))
385 {
386 WARN(("err"));
387 return rc;
388 }
389
390 rc = windowDimensionsSync(true);
391 if (!RT_SUCCESS(rc))
392 {
393 WARN(("err"));
394 mpWindow->UpdateEnd();
395 return rc;
396 }
397
398 rc = windowSetCompositor(false);
399 if (!RT_SUCCESS(rc))
400 {
401 WARN(("err"));
402 mpWindow->UpdateEnd();
403 return rc;
404 }
405
406 mpWindow->UpdateEnd();
407
408 return VINF_SUCCESS;
409}
410
411
412int CrFbDisplayWindow::fbCleanup()
413{
414 int rc = windowCleanup();
415 if (!RT_SUCCESS(rc))
416 {
417 WARN(("windowCleanup failed"));
418 return rc;
419 }
420 return CrFbDisplayBase::fbCleanup();
421}
422
423
424bool CrFbDisplayWindow::isActive()
425{
426 HCR_FRAMEBUFFER hFb = getFramebuffer();
427 return hFb && CrFbIsEnabled(hFb);
428}
429
430
431int CrFbDisplayWindow::windowDimensionsSync(bool fForceCleanup)
432{
433 int rc = VINF_SUCCESS;
434
435 if (!mpWindow)
436 return VINF_SUCCESS;
437
438 //HCR_FRAMEBUFFER hFb = getFramebuffer();
439 if (!fForceCleanup && isActive())
440 {
441 const RTRECT* pRect = getRect();
442
443 if (mpWindow->GetParentId() != mParentId)
444 {
445 rc = mpWindow->Reparent(mParentId);
446 if (!RT_SUCCESS(rc))
447 {
448 WARN(("err"));
449 return rc;
450 }
451 }
452
453 rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop);
454 if (!RT_SUCCESS(rc))
455 {
456 WARN(("err"));
457 return rc;
458 }
459
460 setRegionsChanged();
461
462 rc = mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop));
463 if (!RT_SUCCESS(rc))
464 {
465 WARN(("err"));
466 return rc;
467 }
468
469 rc = mpWindow->SetVisible(!g_CrPresenter.fWindowsForceHidden);
470 if (!RT_SUCCESS(rc))
471 {
472 WARN(("err"));
473 return rc;
474 }
475 }
476 else
477 {
478 rc = mpWindow->SetVisible(false);
479 if (!RT_SUCCESS(rc))
480 {
481 WARN(("err"));
482 return rc;
483 }
484#if 0
485 rc = mpWindow->Reparent(mDefaultParentId);
486 if (!RT_SUCCESS(rc))
487 {
488 WARN(("err"));
489 return rc;
490 }
491#endif
492 }
493
494 return rc;
495}
496
497
498int CrFbDisplayWindow::windowSync()
499{
500 if (!mpWindow)
501 return VINF_SUCCESS;
502
503 int rc = mpWindow->UpdateBegin();
504 if (!RT_SUCCESS(rc))
505 {
506 WARN(("err"));
507 return rc;
508 }
509
510 rc = windowSetCompositor(true);
511 if (!RT_SUCCESS(rc))
512 {
513 WARN(("err"));
514 mpWindow->UpdateEnd();
515 return rc;
516 }
517
518 rc = windowDimensionsSync();
519 if (!RT_SUCCESS(rc))
520 {
521 WARN(("err"));
522 mpWindow->UpdateEnd();
523 return rc;
524 }
525
526 mpWindow->UpdateEnd();
527
528 return rc;
529}
530
531
532int CrFbDisplayWindow::fbSync()
533{
534 int rc = CrFbDisplayBase::fbSync();
535 if (!RT_SUCCESS(rc))
536 {
537 WARN(("err"));
538 return rc;
539 }
540
541 HCR_FRAMEBUFFER hFb = getFramebuffer();
542
543 mu32Screen = CrFbGetScreenInfo(hFb)->u32ViewIndex;
544
545 rc = windowSync();
546 if (!RT_SUCCESS(rc))
547 {
548 WARN(("windowSync failed %d", rc));
549 return rc;
550 }
551
552 if (CrFbHas3DData(hFb))
553 {
554 if (mpWindow && mpWindow->GetParentId())
555 {
556 rc = mpWindow->Create();
557 if (!RT_SUCCESS(rc))
558 {
559 WARN(("err"));
560 return rc;
561 }
562 }
563 }
564
565 return VINF_SUCCESS;
566}
567
568
569const struct RTRECT* CrFbDisplayWindow::getRect()
570{
571 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(getFramebuffer());
572 return CrVrScrCompositorRectGet(pCompositor);
573}
574
Note: See TracBrowser for help on using the repository browser.

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