VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/presenter/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: 8.0 KB
Line 
1/* $Id: window.cpp 53157 2014-10-27 17:24:02Z 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{
32 mFlags.Value = 0;
33}
34
35
36bool CrFbWindow::IsCreated() const
37{
38 return !!mSpuWindow;
39}
40
41bool CrFbWindow::IsVisivle() const
42{
43 return mFlags.fVisible;
44}
45
46
47void CrFbWindow::Destroy()
48{
49 CRASSERT(!mcUpdates);
50
51 if (!mSpuWindow)
52 return;
53
54 cr_server.head_spu->dispatch_table.WindowDestroy(mSpuWindow);
55
56 mSpuWindow = 0;
57 mFlags.fDataPresented = 0;
58}
59
60
61int CrFbWindow::Reparent(uint64_t parentId)
62{
63 crDebug("CrFbWindow: reparent to %p (current mxPos=%d, myPos=%d, mWidth=%u, mHeight=%u)",
64 parentId, mxPos, myPos, mWidth, mHeight);
65
66 if (!checkInitedUpdating())
67 {
68 WARN(("err"));
69 return VERR_INVALID_STATE;
70 }
71
72 uint64_t oldParentId = mParentId;
73
74 mParentId = parentId;
75
76 if (mSpuWindow)
77 {
78 if (oldParentId && !parentId && mFlags.fVisible)
79 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, false);
80
81 renderspuSetWindowId(mParentId);
82 renderspuReparentWindow(mSpuWindow);
83
84 if (parentId)
85 {
86 if (mFlags.fVisible)
87 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
88 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, mFlags.fVisible);
89 }
90 }
91
92 return VINF_SUCCESS;
93}
94
95
96int CrFbWindow::SetVisible(bool fVisible)
97{
98 if (!checkInitedUpdating())
99 {
100 WARN(("err"));
101 return VERR_INVALID_STATE;
102 }
103
104 LOG(("CrWIN: Visible [%d]", fVisible));
105
106 if (!fVisible != !mFlags.fVisible)
107 {
108 mFlags.fVisible = fVisible;
109 if (mSpuWindow && mParentId)
110 {
111 if (fVisible)
112 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
113 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, fVisible);
114 }
115 }
116
117 return VINF_SUCCESS;
118}
119
120
121int CrFbWindow::SetSize(uint32_t width, uint32_t height)
122{
123 if (!checkInitedUpdating())
124 {
125 WARN(("err"));
126 return VERR_INVALID_STATE;
127 }
128
129 LOG(("CrWIN: Size [%d ; %d]", width, height));
130
131 if (mWidth != width || mHeight != height)
132 {
133 mFlags.fCompositoEntriesModified = 1;
134 mWidth = width;
135 mHeight = height;
136 if (mSpuWindow)
137 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, width, height);
138 }
139
140 return VINF_SUCCESS;
141}
142
143
144int CrFbWindow::SetPosition(int32_t x, int32_t y)
145{
146 if (!checkInitedUpdating())
147 {
148 WARN(("err"));
149 return VERR_INVALID_STATE;
150 }
151
152 LOG(("CrWIN: Pos [%d ; %d]", x, y));
153// always do WindowPosition to ensure window is adjusted properly
154// if (x != mxPos || y != myPos)
155 {
156 mxPos = x;
157 myPos = y;
158 if (mSpuWindow)
159 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, x, y);
160 }
161
162 return VINF_SUCCESS;
163}
164
165
166int CrFbWindow::SetVisibleRegionsChanged()
167{
168 if (!checkInitedUpdating())
169 {
170 WARN(("err"));
171 return VERR_INVALID_STATE;
172 }
173
174 mFlags.fCompositoEntriesModified = 1;
175 return VINF_SUCCESS;
176}
177
178
179int CrFbWindow::SetCompositor(const struct VBOXVR_SCR_COMPOSITOR * pCompositor)
180{
181 if (!checkInitedUpdating())
182 {
183 WARN(("err"));
184 return VERR_INVALID_STATE;
185 }
186
187 mpCompositor = pCompositor;
188 mFlags.fCompositoEntriesModified = 1;
189
190 return VINF_SUCCESS;
191}
192
193
194int CrFbWindow::UpdateBegin()
195{
196 ++mcUpdates;
197 if (mcUpdates > 1)
198 return VINF_SUCCESS;
199
200 Assert(!mFlags.fForcePresentOnReenable);
201// Assert(!mFlags.fCompositoEntriesModified);
202
203 if (mFlags.fDataPresented)
204 {
205 Assert(mSpuWindow);
206 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, NULL, NULL);
207 mFlags.fForcePresentOnReenable = isPresentNeeded();
208 }
209
210 return VINF_SUCCESS;
211}
212
213
214void CrFbWindow::UpdateEnd()
215{
216 --mcUpdates;
217 Assert(mcUpdates < UINT32_MAX/2);
218 if (mcUpdates)
219 return;
220
221 checkRegions();
222
223 if (mSpuWindow)
224 {
225 bool fPresentNeeded = isPresentNeeded();
226 if (fPresentNeeded || mFlags.fForcePresentOnReenable)
227 {
228 mFlags.fForcePresentOnReenable = false;
229 if (mpCompositor)
230 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, mpCompositor, NULL);
231 else
232 {
233 VBOXVR_SCR_COMPOSITOR TmpCompositor;
234 RTRECT Rect;
235 Rect.xLeft = 0;
236 Rect.yTop = 0;
237 Rect.xRight = mWidth;
238 Rect.yBottom = mHeight;
239 CrVrScrCompositorInit(&TmpCompositor, &Rect);
240 /* this is a cleanup operation
241 * empty compositor is guarantid to be released on VBoxPresentComposition return */
242 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, &TmpCompositor, NULL);
243 }
244 g_pLed->Asserted.s.fWriting = 1;
245 }
246
247 /* even if the above branch is entered due to mFlags.fForcePresentOnReenable,
248 * the backend should clean up the compositor as soon as presentation is performed */
249 mFlags.fDataPresented = fPresentNeeded;
250 }
251 else
252 {
253 Assert(!mFlags.fDataPresented);
254 Assert(!mFlags.fForcePresentOnReenable);
255 }
256}
257
258
259uint64_t CrFbWindow::GetParentId()
260{
261 return mParentId;
262}
263
264
265int CrFbWindow::Create()
266{
267 if (mSpuWindow)
268 {
269 WARN(("window already created"));
270 return VINF_ALREADY_INITIALIZED;
271 }
272
273 CRASSERT(cr_server.fVisualBitsDefault);
274 renderspuSetWindowId(mParentId);
275 mSpuWindow = cr_server.head_spu->dispatch_table.WindowCreate("", cr_server.fVisualBitsDefault);
276 renderspuSetWindowId(cr_server.screen[0].winID);
277 if (mSpuWindow < 0) {
278 WARN(("WindowCreate failed"));
279 return VERR_GENERAL_FAILURE;
280 }
281
282 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, mWidth, mHeight);
283 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
284
285 checkRegions();
286
287 if (mParentId && mFlags.fVisible)
288 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, true);
289
290 crDebug("CrFbWindow: create window with parent %p (mxPos=%d, myPos=%d, mWidth=%u, mHeight=%u)",
291 mParentId, mxPos, myPos, mWidth, mHeight);
292
293 return VINF_SUCCESS;
294}
295
296
297CrFbWindow::~CrFbWindow()
298{
299 Destroy();
300}
301
302
303void CrFbWindow::checkRegions()
304{
305 if (!mSpuWindow)
306 return;
307
308 if (!mFlags.fCompositoEntriesModified)
309 return;
310
311 uint32_t cRects;
312 const RTRECT *pRects;
313 if (mpCompositor)
314 {
315 int rc = CrVrScrCompositorRegionsGet(mpCompositor, &cRects, NULL, &pRects, NULL);
316 if (!RT_SUCCESS(rc))
317 {
318 WARN(("CrVrScrCompositorRegionsGet failed rc %d", rc));
319 cRects = 0;
320 pRects = NULL;
321 }
322 }
323 else
324 {
325 cRects = 0;
326 pRects = NULL;
327 }
328
329 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mSpuWindow, cRects, (const GLint*)pRects);
330
331 mFlags.fCompositoEntriesModified = 0;
332}
333
334
335bool CrFbWindow::isPresentNeeded()
336{
337 return mFlags.fVisible && mWidth && mHeight && mpCompositor && !CrVrScrCompositorIsEmpty(mpCompositor);
338}
339
340
341bool CrFbWindow::checkInitedUpdating()
342{
343 if (!mcUpdates)
344 {
345 WARN(("not updating"));
346 return false;
347 }
348
349 return true;
350}
351
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