VirtualBox

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

Last change on this file since 53157 was 53157, checked in by vboxsync, 11 years ago

Host 3D: Chronium server: Presentation framework: fixed resources leak (needs more testing on hosts other than X11).

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