VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp@ 45201

Last change on this file since 45201 was 45201, checked in by vboxsync, 12 years ago

crOpenGL: basics for BlitFramebuffer driver bugs work around

  • Property svn:executable set to *
File size: 19.0 KB
Line 
1/* $Id$ */
2
3/** @file
4 * Blitter API implementation
5 */
6/*
7 * Copyright (C) 2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#include "cr_blitter.h"
18#include "cr_spu.h"
19#include "chromium.h"
20#include "cr_error.h"
21#include "cr_net.h"
22#include "cr_rand.h"
23#include "cr_mem.h"
24#include "cr_string.h"
25
26#include <iprt/cdefs.h>
27#include <iprt/types.h>
28#include <iprt/mem.h>
29
30
31int CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, SPUDispatchTable *pDispatch)
32{
33 if (pCtxBase->Base.id == 0 || pCtxBase->Base.id < -1)
34 {
35 crWarning("Default share context not initialized!");
36 return VERR_INVALID_PARAMETER;
37 }
38
39 memset(pBlitter, 0, sizeof (*pBlitter));
40
41 pBlitter->pDispatch = pDispatch;
42 pBlitter->CtxInfo = *pCtxBase;
43 if (fCreateNewCtx)
44 {
45 pBlitter->CtxInfo.Base.id = pDispatch->CreateContext("", pCtxBase->Base.visualBits, pCtxBase->Base.id);
46 if (!pBlitter->CtxInfo.Base.id)
47 {
48 memset(pBlitter, 0, sizeof (*pBlitter));
49 crWarning("CreateContext failed!");
50 return VERR_GENERAL_FAILURE;
51 }
52 pBlitter->Flags.CtxCreated = 1;
53 }
54
55 return VINF_SUCCESS;
56}
57
58void CrBltTerm(PCR_BLITTER pBlitter)
59{
60 if (pBlitter->Flags.CtxCreated)
61 pBlitter->pDispatch->DestroyContext(pBlitter->CtxInfo.Base.id);
62}
63
64void CrBltMuralSetCurrent(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural)
65{
66 if (pMural)
67 {
68 if (!memcmp(&pBlitter->CurrentMural, pMural, sizeof (pBlitter->CurrentMural)))
69 return;
70 memcpy(&pBlitter->CurrentMural, pMural, sizeof (pBlitter->CurrentMural));
71 }
72 else
73 {
74 if (!pBlitter->CurrentMural.Base.id)
75 return;
76 pBlitter->CurrentMural.Base.id = 0;
77 }
78
79 pBlitter->Flags.CurrentMuralChanged = 1;
80
81 if (!CrBltIsEntered(pBlitter))
82 return;
83
84 if (pMural)
85 pBlitter->pDispatch->MakeCurrent(pMural->Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
86 else
87 pBlitter->pDispatch->MakeCurrent(0, 0, 0);
88}
89
90static DECLCALLBACK(int) crBltBlitTexBufImplFbo(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
91{
92 GLenum filter = CRBLT_FILTER_FROM_FLAGS(fFlags);
93 pBlitter->pDispatch->BindFramebufferEXT(GL_READ_FRAMEBUFFER, pBlitter->idFBO);
94 pBlitter->pDispatch->FramebufferTexture2DEXT(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pSrc->target, pSrc->hwid, 0);
95 pBlitter->pDispatch->ReadBuffer(GL_COLOR_ATTACHMENT0);
96
97 for (uint32_t i = 0; i < cRects; ++i)
98 {
99 const RTRECT * pSrcRect = &paSrcRect[i];
100 const RTRECT * pDstRect = &paDstRect[i];
101 int32_t srcY1;
102 int32_t srcY2;
103 int32_t dstY1;
104 int32_t dstY2;
105 int32_t srcX1 = pSrcRect->xLeft;
106 int32_t srcX2 = pSrcRect->xRight;
107 int32_t dstX1 = pDstRect->xLeft;
108 int32_t dstX2 = pDstRect->xRight;
109
110 if (CRBLT_F_INVERT_SRC_YCOORDS & fFlags)
111 {
112 srcY1 = pSrc->height - pSrcRect->yTop;
113 srcY2 = pSrc->height - pSrcRect->yBottom;
114 }
115 else
116 {
117 srcY1 = pSrcRect->yTop;
118 srcY2 = pSrcRect->yBottom;
119 }
120
121 if (CRBLT_F_INVERT_DST_YCOORDS & fFlags)
122 {
123 dstY1 = pDstSize->cy - pDstRect->yTop;
124 dstY2 = pDstSize->cy - pDstRect->yBottom;
125 }
126 else
127 {
128 dstY1 = pDstRect->yTop;
129 dstY2 = pDstRect->yBottom;
130 }
131
132 if (srcY1 > srcY2)
133 {
134 if (dstY1 > dstY2)
135 {
136 /* use srcY1 < srcY2 && dstY1 < dstY2 whenever possible to avoid GPU driver bugs */
137 int32_t tmp = srcY1;
138 srcY1 = srcY2;
139 srcY2 = tmp;
140 tmp = dstY1;
141 dstY1 = dstY2;
142 dstY2 = tmp;
143 }
144 }
145
146 if (srcX1 > srcX2)
147 {
148 if (dstX1 > dstX2)
149 {
150 /* use srcX1 < srcX2 && dstX1 < dstX2 whenever possible to avoid GPU driver bugs */
151 int32_t tmp = srcX1;
152 srcX1 = srcX2;
153 srcX2 = tmp;
154 tmp = dstX1;
155 dstX1 = dstX2;
156 dstX2 = tmp;
157 }
158 }
159
160 pBlitter->pDispatch->BlitFramebufferEXT(srcX1, srcY1, srcX2, srcY2,
161 dstX1, dstY1, dstX2, dstY2,
162 GL_COLOR_BUFFER_BIT, filter);
163 }
164
165 return VINF_SUCCESS;
166}
167
168/* GL_TRIANGLE_FAN */
169DECLINLINE(GLfloat*) crBltVtRectTFNormalized(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, uint32_t height)
170{
171 /* going ccw:
172 * 1. (left;top) 4. (right;top)
173 * | ^
174 * > |
175 * 2. (left;bottom) -> 3. (right;bottom) */
176 /* xLeft yTop */
177 pBuff[0] = ((float)pRect->xLeft)/((float)normalX);
178 pBuff[1] = ((float)(height ? height - pRect->yTop : pRect->yTop))/((float)normalY);
179
180 /* xLeft yBottom */
181 pBuff[2] = pBuff[0];
182 pBuff[3] = ((float)(height ? height - pRect->yBottom : pRect->yBottom))/((float)normalY);
183
184 /* xRight yBottom */
185 pBuff[4] = ((float)pRect->xRight)/((float)normalX);
186 pBuff[5] = pBuff[3];
187
188 /* xRight yTop */
189 pBuff[6] = pBuff[4];
190 pBuff[7] = pBuff[1];
191 return &pBuff[8];
192}
193
194DECLINLINE(GLint*) crBltVtRectTF(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLint* pBuff, uint32_t height)
195{
196 /* xLeft yTop */
197 pBuff[0] = pRect->xLeft;
198 pBuff[1] = height ? height - pRect->yTop : pRect->yTop;
199
200 /* xLeft yBottom */
201 pBuff[2] = pBuff[0];
202 pBuff[3] = height ? height - pRect->yBottom : pRect->yBottom;
203
204 /* xRight yBottom */
205 pBuff[4] = pRect->xRight;
206 pBuff[5] = pBuff[3];
207
208 /* xRight yTop */
209 pBuff[6] = pBuff[4];
210 pBuff[7] = pBuff[1];
211 return &pBuff[8];
212}
213
214DECLINLINE(GLubyte*) crBltVtFillRectIndicies(GLubyte *pIndex, GLubyte *piBase)
215{
216 GLubyte iBase = *piBase;
217 /* triangle 1 */
218 pIndex[0] = iBase;
219 pIndex[1] = iBase + 1;
220 pIndex[2] = iBase + 2;
221
222 /* triangle 2 */
223 pIndex[3] = iBase;
224 pIndex[4] = iBase + 2;
225 pIndex[5] = iBase + 3;
226 *piBase = iBase + 4;
227 return pIndex + 6;
228}
229
230/* Indexed GL_TRIANGLES */
231DECLINLINE(GLfloat*) crBltVtRectITNormalized(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, uint32_t height)
232{
233 GLfloat* ret = crBltVtRectTFNormalized(pRect, normalX, normalY, pBuff, height);
234 return ret;
235}
236
237DECLINLINE(GLint*) crBltVtRectIT(RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLint* pBuff, GLubyte **ppIndex, GLubyte *piBase, uint32_t height)
238{
239 GLint* ret = crBltVtRectTF(pRect, normalX, normalY, pBuff, height);
240
241 if (ppIndex)
242 *ppIndex = crBltVtFillRectIndicies(*ppIndex, piBase);
243
244 return ret;
245}
246
247DECLINLINE(GLuint) crBltVtGetNumVerticiesTF(GLuint cRects)
248{
249 return cRects * 4;
250}
251
252#define crBltVtGetNumVerticiesIT crBltVtGetNumVerticiesTF
253
254DECLINLINE(GLuint) crBltVtGetNumIndiciesIT(GLuint cRects)
255{
256 return 6 * cRects;
257}
258
259
260static GLfloat* crBltVtRectsITNormalized(const RTRECT *paRects, uint32_t cRects, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, GLubyte **ppIndex, GLubyte *piBase, uint32_t height)
261{
262 uint32_t i;
263 for (i = 0; i < cRects; ++i)
264 {
265 pBuff = crBltVtRectITNormalized(&paRects[i], normalX, normalY, pBuff, height);
266 }
267
268
269 if (ppIndex)
270 {
271 GLubyte *pIndex = (GLubyte*)pBuff;
272 *ppIndex = pIndex;
273 for (i = 0; i < cRects; ++i)
274 {
275 pIndex = crBltVtFillRectIndicies(pIndex, piBase);
276 }
277 pBuff = (GLfloat*)pIndex;
278 }
279
280 return pBuff;
281}
282
283static void* crBltBufGet(PCR_BLITTER_BUFFER pBuffer, GLuint cbBuffer)
284{
285 if (pBuffer->cbBuffer < cbBuffer)
286 {
287 if (pBuffer->pvBuffer)
288 {
289 RTMemFree(pBuffer->pvBuffer);
290 }
291
292#ifndef DEBUG_misha
293 /* debugging: ensure we calculate proper buffer size */
294 cbBuffer += 16;
295#endif
296
297 pBuffer->pvBuffer = RTMemAlloc(cbBuffer);
298 if (pBuffer->pvBuffer)
299 pBuffer->cbBuffer = cbBuffer;
300 else
301 {
302 crWarning("failed to allocate buffer of size %d", cbBuffer);
303 pBuffer->cbBuffer = 0;
304 }
305 }
306 return pBuffer->pvBuffer;
307}
308
309static void crBltCheckSetupViewport(PCR_BLITTER pBlitter, const RTRECTSIZE *pDstSize, bool fFBODraw)
310{
311 bool fUpdateViewport = pBlitter->Flags.CurrentMuralChanged;
312 if (pBlitter->CurrentSetSize.cx != pDstSize->cx
313 || pBlitter->CurrentSetSize.cy != pDstSize->cy)
314 {
315 pBlitter->CurrentSetSize = *pDstSize;
316 pBlitter->pDispatch->MatrixMode(GL_PROJECTION);
317 pBlitter->pDispatch->LoadIdentity();
318 pBlitter->pDispatch->Ortho(0, pDstSize->cx, 0, pDstSize->cy, -1, 1);
319 fUpdateViewport = true;
320 }
321
322 if (fUpdateViewport)
323 {
324 pBlitter->pDispatch->Viewport(0, 0, pBlitter->CurrentSetSize.cx, pBlitter->CurrentSetSize.cy);
325 pBlitter->Flags.CurrentMuralChanged = 0;
326 }
327
328 pBlitter->Flags.LastWasFBODraw = fFBODraw;
329}
330
331static DECLCALLBACK(int) crBltBlitTexBufImplDraw2D(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
332{
333 GLuint normalX, normalY;
334 uint32_t srcHeight = (fFlags & CRBLT_F_INVERT_SRC_YCOORDS) ? pSrc->height : 0;
335 uint32_t dstHeight = (fFlags & CRBLT_F_INVERT_DST_YCOORDS) ? pDstSize->cy : 0;
336 Assert(srcHeight == dstHeight);
337
338 switch (pSrc->target)
339 {
340 case GL_TEXTURE_2D:
341 {
342 normalX = pSrc->width;
343 normalY = pSrc->height;
344 break;
345 }
346
347 case GL_TEXTURE_RECTANGLE_ARB:
348 {
349 normalX = 1;
350 normalY = 1;
351 break;
352 }
353
354 default:
355 {
356 crWarning("Unsupported texture target 0x%x", pSrc->target);
357 return VERR_INVALID_PARAMETER;
358 }
359 }
360
361 Assert(pSrc->hwid);
362
363 pBlitter->pDispatch->BindTexture(pSrc->target, pSrc->hwid);
364
365 if (cRects == 1)
366 {
367 /* just optimizatino to draw a single rect with GL_TRIANGLE_FAN */
368 bool bUseSameVerticies = paSrcRect == paDstRect && normalX == 1 && normalY == 1 && srcHeight == dstHeight;
369 GLfloat *pVerticies;
370 GLfloat *pTexCoords;
371 GLuint cElements = crBltVtGetNumVerticiesTF(1);
372 if (bUseSameVerticies)
373 {
374 pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * sizeof (*pVerticies));
375 crBltVtRectTFNormalized(paDstRect, normalX, normalY, pVerticies, dstHeight);
376 pTexCoords = pVerticies;
377 }
378 else
379 {
380 pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * 2 * sizeof (*pVerticies));
381 pTexCoords = crBltVtRectTFNormalized(paDstRect, 1, 1, pVerticies, dstHeight);
382 crBltVtRectTFNormalized(paSrcRect, normalX, normalY, pTexCoords, srcHeight);
383 }
384
385 pBlitter->pDispatch->EnableClientState(GL_VERTEX_ARRAY);
386 pBlitter->pDispatch->VertexPointer(2, GL_FLOAT, 0, pVerticies);
387
388 pBlitter->pDispatch->EnableClientState(GL_TEXTURE_COORD_ARRAY);
389 pBlitter->pDispatch->TexCoordPointer(2, GL_FLOAT, 0, pTexCoords);
390
391 pBlitter->pDispatch->Enable(pSrc->target);
392
393 pBlitter->pDispatch->DrawArrays(GL_TRIANGLE_FAN, 0, cElements);
394
395 pBlitter->pDispatch->Disable(pSrc->target);
396
397 pBlitter->pDispatch->DisableClientState(GL_TEXTURE_COORD_ARRAY);
398 pBlitter->pDispatch->DisableClientState(GL_VERTEX_ARRAY);
399 }
400 else
401 {
402 bool bUseSameVerticies = paSrcRect == paDstRect && normalX == 1 && normalY == 1 && srcHeight == dstHeight;
403 GLfloat *pVerticies;
404 GLfloat *pTexCoords;
405 GLubyte *pIndicies;
406 GLuint cElements = crBltVtGetNumVerticiesIT(cRects);
407 GLuint cIndicies = crBltVtGetNumIndiciesIT(cRects);
408 GLubyte iIdxBase = 0;
409 if (bUseSameVerticies)
410 {
411 pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * sizeof (*pVerticies) + cIndicies * sizeof (*pIndicies));
412 crBltVtRectsITNormalized(paDstRect, cRects, normalX, normalY, pVerticies, &pIndicies, &iIdxBase, dstHeight);
413 pTexCoords = pVerticies;
414 }
415 else
416 {
417 pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * 2 * sizeof (*pVerticies) + cIndicies * sizeof (*pIndicies));
418 pTexCoords = crBltVtRectsITNormalized(paDstRect, cRects, 1, 1, pVerticies, &pIndicies, &iIdxBase, dstHeight);
419 crBltVtRectsITNormalized(paSrcRect, cRects, normalX, normalY, pTexCoords, NULL, NULL, srcHeight);
420 }
421
422 pBlitter->pDispatch->EnableClientState(GL_VERTEX_ARRAY);
423 pBlitter->pDispatch->VertexPointer(2, GL_FLOAT, 0, pVerticies);
424
425 pBlitter->pDispatch->EnableClientState(GL_TEXTURE_COORD_ARRAY);
426 pBlitter->pDispatch->TexCoordPointer(2, GL_FLOAT, 0, pTexCoords);
427
428 pBlitter->pDispatch->Enable(pSrc->target);
429
430 pBlitter->pDispatch->DrawElements(GL_TRIANGLES, cIndicies, GL_UNSIGNED_BYTE, pIndicies);
431
432 pBlitter->pDispatch->Disable(pSrc->target);
433
434 pBlitter->pDispatch->DisableClientState(GL_TEXTURE_COORD_ARRAY);
435 pBlitter->pDispatch->DisableClientState(GL_VERTEX_ARRAY);
436 }
437
438 return VINF_SUCCESS;
439}
440
441static int crBltInitOnMakeCurent(PCR_BLITTER pBlitter)
442{
443 const char * pszExtension = (const char*)pBlitter->pDispatch->GetString(GL_EXTENSIONS);
444 if (crStrstr(pszExtension, "GL_EXT_framebuffer_object"))
445 {
446 pBlitter->Flags.SupportsFBO = 1;
447 pBlitter->pDispatch->GenFramebuffersEXT(1, &pBlitter->idFBO);
448 Assert(pBlitter->idFBO);
449 }
450 else
451 crWarning("GL_EXT_framebuffer_object not supported, blitter can only blit to window");
452
453 /* BlitFramebuffer seems to be buggy on Intel,
454 * try always glDrawXxx for now */
455 if (0 && crStrstr(pszExtension, "GL_EXT_framebuffer_blit"))
456 {
457 pBlitter->Flags.SupportsFBOBlit = 1;
458 pBlitter->pfnBlt = crBltBlitTexBufImplFbo;
459 }
460 else
461 {
462// crWarning("GL_EXT_framebuffer_blit not supported, will use Draw functions for blitting, which might be less efficient");
463 pBlitter->pfnBlt = crBltBlitTexBufImplDraw2D;
464 }
465
466 /* defaults. but just in case */
467 pBlitter->pDispatch->MatrixMode(GL_TEXTURE);
468 pBlitter->pDispatch->LoadIdentity();
469 pBlitter->pDispatch->MatrixMode(GL_MODELVIEW);
470 pBlitter->pDispatch->LoadIdentity();
471
472 return VINF_SUCCESS;
473}
474
475void CrBltLeave(PCR_BLITTER pBlitter)
476{
477 Assert(CrBltIsEntered(pBlitter));
478
479 if (pBlitter->Flags.SupportsFBO)
480 {
481 pBlitter->pDispatch->BindFramebufferEXT(GL_FRAMEBUFFER, 0);
482 pBlitter->pDispatch->DrawBuffer(GL_BACK);
483 pBlitter->pDispatch->ReadBuffer(GL_BACK);
484 }
485
486 pBlitter->pDispatch->Flush();
487
488 if (pBlitter->pRestoreCtxInfo != &pBlitter->CtxInfo)
489 {
490 pBlitter->pDispatch->MakeCurrent(pBlitter->pRestoreMural->Base.id, 0, pBlitter->pRestoreCtxInfo->Base.id);
491 }
492 else
493 {
494 pBlitter->pDispatch->MakeCurrent(0, 0, 0);
495 }
496
497 pBlitter->pRestoreCtxInfo = NULL;
498}
499
500int CrBltEnter(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural)
501{
502 if (!pBlitter->CurrentMural.Base.id)
503 {
504 crWarning("current mural not initialized!");
505 return VERR_INVALID_STATE;
506 }
507
508 if (CrBltIsEntered(pBlitter))
509 {
510 crWarning("blitter is entered already!");
511 return VERR_INVALID_STATE;
512 }
513
514 if (pRestoreCtxInfo)
515 {
516 pBlitter->pRestoreCtxInfo = pRestoreCtxInfo;
517 pBlitter->pRestoreMural = pRestoreMural;
518
519 pBlitter->pDispatch->Flush();
520 }
521 else
522 {
523 pBlitter->pRestoreCtxInfo = &pBlitter->CtxInfo;
524 }
525
526 pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
527
528 if (pBlitter->Flags.Initialized)
529 return VINF_SUCCESS;
530
531 int rc = crBltInitOnMakeCurent(pBlitter);
532 if (RT_SUCCESS(rc))
533 {
534 pBlitter->Flags.Initialized = 1;
535 return VINF_SUCCESS;
536 }
537
538 crWarning("crBltInitOnMakeCurent failed, rc %d", rc);
539 CrBltLeave(pBlitter);
540 return rc;
541}
542
543static void crBltBlitTexBuf(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, GLenum enmDstBuff, const RTRECTSIZE *pDstSize, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
544{
545 pBlitter->pDispatch->DrawBuffer(enmDstBuff);
546
547 crBltCheckSetupViewport(pBlitter, pDstSize, enmDstBuff == GL_DRAW_FRAMEBUFFER);
548
549 pBlitter->pfnBlt(pBlitter, pSrc, paSrcRects, pDstSize, paDstRects, cRects, fFlags);
550}
551
552void CrBltBlitTexMural(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
553{
554 RTRECTSIZE DstSize = {pBlitter->CurrentMural.width, pBlitter->CurrentMural.height};
555
556 pBlitter->pDispatch->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
557
558 crBltBlitTexBuf(pBlitter, pSrc, paSrcRects, GL_BACK, &DstSize, paDstRects, cRects, fFlags);
559}
560
561void CrBltBlitTexTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *pSrcRect, const VBOXVR_TEXTURE *pDst, const RTRECT *pDstRect, uint32_t cRects, uint32_t fFlags)
562{
563 RTRECTSIZE DstSize = {(uint32_t)pDst->width, (uint32_t)pDst->height};
564
565 pBlitter->pDispatch->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, pBlitter->idFBO);
566
567 /* TODO: mag/min filters ? */
568
569 pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pDst->target, pDst->hwid, 0);
570
571// pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
572// pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
573
574 crBltBlitTexBuf(pBlitter, pSrc, pSrcRect, GL_DRAW_FRAMEBUFFER, &DstSize, pDstRect, cRects, fFlags);
575}
576
577void CrBltPresent(PCR_BLITTER pBlitter)
578{
579 if (pBlitter->CtxInfo.Base.visualBits & CR_DOUBLE_BIT)
580 pBlitter->pDispatch->SwapBuffers(pBlitter->CurrentMural.Base.id, 0);
581 else
582 pBlitter->pDispatch->Flush();
583}
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