VirtualBox

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

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

crOpenGL: offscreen rendering & VRDP+3D-related fixes

  • Property svn:executable set to *
File size: 17.6 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, CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, SPUDispatchTable *pDispatch)
32{
33 memset(pBlitter, 0, sizeof (*pBlitter));
34
35 pBlitter->pDispatch = pDispatch;
36
37 if (pCtxBase->Base.id == 0 || pCtxBase->Base.id < -1)
38 {
39 crWarning("Default share context not initialized!");
40 return VERR_INVALID_PARAMETER;
41 }
42
43 pBlitter->CtxInfo = *pCtxBase;
44 if (fCreateNewCtx)
45 {
46 pBlitter->CtxInfo.Base.id = pDispatch->CreateContext("", pCtxBase->Base.visualBits, pCtxBase->Base.id);
47 if (!pBlitter->CtxInfo.Base.id)
48 {
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, CR_BLITTER_WINDOW *pMural)
65{
66 if (pBlitter->pCurrentMural == pMural)
67 return;
68
69 pBlitter->pCurrentMural = pMural;
70 pBlitter->Flags.CurrentMuralChanged = 1;
71
72 if (!CrBltIsEntered(pBlitter))
73 return;
74
75 if (pMural)
76 pBlitter->pDispatch->MakeCurrent(pMural->Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
77 else
78 pBlitter->pDispatch->MakeCurrent(0, 0, 0);
79}
80
81#define CRBLT_FILTER_FROM_FLAGS(_f) (((_f) & CRBLT_F_LINEAR) ? GL_LINEAR : GL_NEAREST)
82
83static DECLCALLBACK(int) crBltBlitTexBufImplFbo(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const PRTRECTSIZE pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
84{
85 GLenum filter = CRBLT_FILTER_FROM_FLAGS(fFlags);
86 pBlitter->pDispatch->BindFramebufferEXT(GL_READ_FRAMEBUFFER, pBlitter->idFBO);
87 pBlitter->pDispatch->FramebufferTexture2DEXT(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pSrc->target, pSrc->hwid, 0);
88 pBlitter->pDispatch->ReadBuffer(GL_COLOR_ATTACHMENT0);
89
90 for (uint32_t i = 0; i < cRects; ++i)
91 {
92 const RTRECT * pSrcRect = &paSrcRect[i];
93 const RTRECT * pDstRect = &paDstRect[i];
94 if (CRBLT_F_OFFSCREEN & fFlags)
95 {
96 pBlitter->pDispatch->BlitFramebufferEXT(
97 pSrcRect->xLeft, pSrcRect->yTop, pSrcRect->xRight, pSrcRect->yBottom,
98 pDstRect->xLeft, pDstRect->yTop, pDstRect->xRight, pDstRect->yBottom,
99 GL_COLOR_BUFFER_BIT, filter);
100 }
101 else
102 {
103 pBlitter->pDispatch->BlitFramebufferEXT(
104 pSrcRect->xLeft, pSrc->height - pSrcRect->yTop, pSrcRect->xRight, pSrc->height - pSrcRect->yBottom,
105 pDstRect->xLeft, pDstSize->cy - pDstRect->yTop, pDstRect->xRight, pDstSize->cy - pDstRect->yBottom,
106 GL_COLOR_BUFFER_BIT, filter);
107 }
108 }
109
110 return VINF_SUCCESS;
111}
112
113/* GL_TRIANGLE_FAN */
114DECLINLINE(GLfloat*) crBltVtRectTFNormalized(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLfloat* pBuff)
115{
116 /* going ccw:
117 * 1. (left;top) 4. (right;top)
118 * | ^
119 * > |
120 * 2. (left;bottom) -> 3. (right;bottom) */
121 /* xLeft yTop */
122 pBuff[0] = ((float)pRect->xLeft)/((float)normalX);
123 pBuff[1] = ((float)pRect->yTop)/((float)normalY);
124
125 /* xLeft yBottom */
126 pBuff[2] = pBuff[0];
127 pBuff[3] = ((float)pRect->yBottom)/((float)normalY);
128
129 /* xRight yBottom */
130 pBuff[4] = ((float)pRect->xRight)/((float)normalX);
131 pBuff[5] = pBuff[3];
132
133 /* xRight yTop */
134 pBuff[6] = pBuff[4];
135 pBuff[7] = pBuff[1];
136 return &pBuff[8];
137}
138
139DECLINLINE(GLint*) crBltVtRectTF(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLint* pBuff)
140{
141 /* xLeft yTop */
142 pBuff[0] = pRect->xLeft;
143 pBuff[1] = pRect->yTop;
144
145 /* xLeft yBottom */
146 pBuff[2] = pBuff[0];
147 pBuff[3] = pRect->yBottom;
148
149 /* xRight yBottom */
150 pBuff[4] = pRect->xRight;
151 pBuff[5] = pBuff[3];
152
153 /* xRight yTop */
154 pBuff[6] = pBuff[4];
155 pBuff[7] = pBuff[1];
156 return &pBuff[8];
157}
158
159DECLINLINE(GLubyte*) crBltVtFillRectIndicies(GLubyte *pIndex, GLubyte *piBase)
160{
161 GLubyte iBase = *piBase;
162 /* triangle 1 */
163 pIndex[0] = iBase;
164 pIndex[1] = iBase + 1;
165 pIndex[2] = iBase + 2;
166
167 /* triangle 2 */
168 pIndex[3] = iBase;
169 pIndex[4] = iBase + 2;
170 pIndex[5] = iBase + 3;
171 *piBase = iBase + 6;
172 return pIndex + 6;
173}
174
175/* Indexed GL_TRIANGLES */
176DECLINLINE(GLfloat*) crBltVtRectITNormalized(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLfloat* pBuff)
177{
178 GLfloat* ret = crBltVtRectTFNormalized(pRect, normalX, normalY, pBuff);
179 return ret;
180}
181
182DECLINLINE(GLint*) crBltVtRectIT(RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLint* pBuff, GLubyte **ppIndex, GLubyte *piBase)
183{
184 GLint* ret = crBltVtRectTF(pRect, normalX, normalY, pBuff);
185
186 if (ppIndex)
187 *ppIndex = crBltVtFillRectIndicies(*ppIndex, piBase);
188
189 return ret;
190}
191
192DECLINLINE(GLuint) crBltVtGetNumVerticiesTF(GLuint cRects)
193{
194 return cRects * 4;
195}
196
197#define crBltVtGetNumVerticiesIT crBltVtGetNumVerticiesTF
198
199DECLINLINE(GLuint) crBltVtGetNumIndiciesIT(GLuint cRects)
200{
201 return 6 * cRects;
202}
203
204
205static GLfloat* crBltVtRectsITNormalized(const RTRECT *paRects, uint32_t cRects, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, GLubyte **ppIndex, GLubyte *piBase)
206{
207 uint32_t i;
208 for (i = 0; i < cRects; ++i)
209 {
210 pBuff = crBltVtRectITNormalized(&paRects[i], normalX, normalY, pBuff);
211 }
212
213
214 if (ppIndex)
215 {
216 GLubyte *pIndex = (GLubyte*)pBuff;
217 *ppIndex = pIndex;
218 for (i = 0; i < cRects; ++i)
219 {
220 pIndex = crBltVtFillRectIndicies(pIndex, piBase);
221 }
222 pBuff = (GLfloat*)pIndex;
223 }
224
225 return pBuff;
226}
227
228static void* crBltBufGet(PCR_BLITTER_BUFFER pBuffer, GLuint cbBuffer)
229{
230 if (pBuffer->cbBuffer < cbBuffer)
231 {
232 if (pBuffer->pvBuffer)
233 {
234 RTMemFree(pBuffer->pvBuffer);
235 }
236
237 cbBuffer += 16;
238
239 pBuffer->pvBuffer = RTMemAlloc(cbBuffer);
240 if (pBuffer->pvBuffer)
241 pBuffer->cbBuffer = cbBuffer;
242 else
243 {
244 crWarning("failed to allocate buffer of size %d", cbBuffer);
245 pBuffer->cbBuffer = 0;
246 }
247 }
248 return pBuffer->pvBuffer;
249}
250
251static void crBltCheckSetupViewport(PCR_BLITTER pBlitter, const PRTRECTSIZE pDstSize, bool fFBODraw)
252{
253 if (!pBlitter->Flags.LastWasFBODraw != !fFBODraw
254 || pBlitter->Flags.CurrentMuralChanged
255 || pBlitter->CurrentSetSize.cx != pDstSize->cx
256 || pBlitter->CurrentSetSize.cy != pDstSize->cy)
257 {
258#if 0
259 const GLdouble aProjection[] =
260 {
261 2.0 / pDstSize->cx, 0.0, 0.0, 0.0,
262 0.0, 2.0 / pDstSize->cy, 0.0, 0.0,
263 0.0, 0.0, 2.0, 0.0,
264 -1.0, -1.0, -1.0, 1.0
265 };
266 pBlitter->pDispatch->MatrixMode(GL_PROJECTION);
267 pBlitter->pDispatch->LoadMatrixd(aProjection);
268 pBlitter->pDispatch->Viewport(0, 0, pDstSize->cx, pDstSize->cy);
269#else
270 pBlitter->pDispatch->MatrixMode(GL_PROJECTION);
271 pBlitter->pDispatch->LoadIdentity();
272 pBlitter->pDispatch->Viewport(0, 0, pDstSize->cx, pDstSize->cy);
273 pBlitter->pDispatch->Ortho(0, pDstSize->cx, 0, pDstSize->cy, -1, 1);
274 pBlitter->pDispatch->MatrixMode(GL_TEXTURE);
275 pBlitter->pDispatch->LoadIdentity();
276 pBlitter->pDispatch->MatrixMode(GL_MODELVIEW);
277 pBlitter->pDispatch->LoadIdentity();
278
279 /* Clear background to transparent */
280 pBlitter->pDispatch->ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
281#endif
282 pBlitter->CurrentSetSize.cx = pDstSize->cx;
283 pBlitter->CurrentSetSize.cy = pDstSize->cy;
284 pBlitter->Flags.LastWasFBODraw = fFBODraw;
285 if (!fFBODraw)
286 pBlitter->Flags.CurrentMuralChanged = 0;
287 }
288}
289
290static DECLCALLBACK(int) crBltBlitTexBufImplDraw2D(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const PRTRECTSIZE pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
291{
292 GLuint normalX, normalY;
293
294 switch (pSrc->target)
295 {
296 case GL_TEXTURE_2D:
297 {
298 normalX = pSrc->width;
299 normalY = pSrc->height;
300 break;
301 }
302
303 case GL_TEXTURE_RECTANGLE_ARB:
304 {
305 normalX = 1;
306 normalY = 1;
307 break;
308 }
309
310 default:
311 {
312 crWarning("Unsupported texture target 0x%x", pSrc->target);
313 return VERR_INVALID_PARAMETER;
314 }
315 }
316
317 Assert(pSrc->hwid);
318
319 pBlitter->pDispatch->BindTexture(pSrc->target, pSrc->hwid);
320
321 if (cRects == 1)
322 {
323 /* just optimizatino to draw a single rect with GL_TRIANGLE_FAN */
324 bool bUseSameVerticies = paSrcRect == paDstRect && normalX == 1 && normalY == 1;
325 GLfloat *pVerticies;
326 GLfloat *pTexCoords;
327 GLuint cElements = crBltVtGetNumVerticiesTF(1);
328 if (bUseSameVerticies)
329 {
330 pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * sizeof (*pVerticies));
331 crBltVtRectTFNormalized(paDstRect, normalX, normalY, pVerticies);
332 pTexCoords = pVerticies;
333 }
334 else
335 {
336 pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * 2 * sizeof (*pVerticies));
337 pTexCoords = crBltVtRectTFNormalized(paDstRect, 1, 1, pVerticies);
338 crBltVtRectTFNormalized(paSrcRect, normalX, normalY, pTexCoords);
339 }
340
341 pBlitter->pDispatch->EnableClientState(GL_VERTEX_ARRAY);
342 pBlitter->pDispatch->VertexPointer(2, GL_FLOAT, 0, pVerticies);
343
344 pBlitter->pDispatch->EnableClientState(GL_TEXTURE_COORD_ARRAY);
345 pBlitter->pDispatch->TexCoordPointer(2, GL_FLOAT, 0, pTexCoords);
346
347 pBlitter->pDispatch->Enable(pSrc->target);
348
349 pBlitter->pDispatch->DrawArrays(GL_TRIANGLE_FAN, 0, cElements);
350
351 pBlitter->pDispatch->Disable(pSrc->target);
352
353 pBlitter->pDispatch->DisableClientState(GL_TEXTURE_COORD_ARRAY);
354 pBlitter->pDispatch->DisableClientState(GL_VERTEX_ARRAY);
355 }
356 else
357 {
358 bool bUseSameVerticies = paSrcRect == paDstRect && normalX == 1 && normalY == 1;
359 GLfloat *pVerticies;
360 GLfloat *pTexCoords;
361 GLubyte *pIndicies;
362 GLuint cElements = crBltVtGetNumVerticiesIT(cRects);
363 GLuint cIndicies = crBltVtGetNumIndiciesIT(cRects);
364 GLubyte iIdxBase = 0;
365 if (bUseSameVerticies)
366 {
367 pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * sizeof (*pVerticies));
368 crBltVtRectsITNormalized(paDstRect, cRects, normalX, normalY, pVerticies, &pIndicies, &iIdxBase);
369 pTexCoords = pVerticies;
370 }
371 else
372 {
373 pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * 2 * sizeof (*pVerticies));
374 pTexCoords = crBltVtRectsITNormalized(paDstRect, cRects, 1, 1, pVerticies, &pIndicies, &iIdxBase);
375 crBltVtRectsITNormalized(paSrcRect, cRects, normalX, normalY, pTexCoords, NULL, NULL);
376 }
377
378 pBlitter->pDispatch->EnableClientState(GL_VERTEX_ARRAY);
379 pBlitter->pDispatch->VertexPointer(2, GL_FLOAT, 0, pVerticies);
380
381 pBlitter->pDispatch->EnableClientState(GL_TEXTURE_COORD_ARRAY);
382 pBlitter->pDispatch->TexCoordPointer(2, GL_FLOAT, 0, pTexCoords);
383
384 pBlitter->pDispatch->Enable(pSrc->target);
385
386 pBlitter->pDispatch->DrawElements(GL_TRIANGLES, cIndicies, GL_UNSIGNED_BYTE, pIndicies);
387
388 pBlitter->pDispatch->Disable(pSrc->target);
389
390 pBlitter->pDispatch->DisableClientState(GL_TEXTURE_COORD_ARRAY);
391 pBlitter->pDispatch->DisableClientState(GL_VERTEX_ARRAY);
392 }
393
394 return VINF_SUCCESS;
395}
396
397static int crBltInitOnMakeCurent(PCR_BLITTER pBlitter)
398{
399 const char * pszExtension = (const char*)pBlitter->pDispatch->GetString(GL_EXTENSIONS);
400 if (crStrstr(pszExtension, "GL_EXT_framebuffer_object"))
401 {
402 pBlitter->Flags.SupportsFBO = 1;
403 pBlitter->pDispatch->GenFramebuffersEXT(1, &pBlitter->idFBO);
404 Assert(pBlitter->idFBO);
405 }
406 else
407 crWarning("GL_EXT_framebuffer_object not supported, blitter can only blit to window");
408
409 if (crStrstr(pszExtension, "GL_EXT_framebuffer_blit"))
410 {
411 pBlitter->Flags.SupportsFBOBlit = 1;
412 pBlitter->pfnBlt = crBltBlitTexBufImplFbo;
413 }
414 else
415 {
416 crWarning("GL_EXT_framebuffer_blit not supported, will use Draw functions for blitting, which might be less efficient");
417 pBlitter->pfnBlt = crBltBlitTexBufImplDraw2D;
418 }
419
420 return VINF_SUCCESS;
421}
422
423void CrBltLeave(PCR_BLITTER pBlitter)
424{
425 Assert(CrBltIsEntered(pBlitter));
426
427 if (pBlitter->Flags.SupportsFBO)
428 {
429 pBlitter->pDispatch->BindFramebufferEXT(GL_FRAMEBUFFER, 0);
430 pBlitter->pDispatch->DrawBuffer(GL_BACK);
431 pBlitter->pDispatch->ReadBuffer(GL_BACK);
432 }
433
434 pBlitter->pDispatch->Flush();
435
436 if (pBlitter->pRestoreCtxInfo != &pBlitter->CtxInfo)
437 {
438
439 pBlitter->pDispatch->MakeCurrent(pBlitter->pRestoreMural->Base.id, 0,
440 pBlitter->pRestoreCtxInfo->Base.id >= 0
441 ? pBlitter->pRestoreCtxInfo->Base.id : pBlitter->pRestoreCtxInfo->Base.id);
442 }
443 else
444 {
445 pBlitter->pDispatch->MakeCurrent(0, 0, 0);
446 }
447
448 pBlitter->pRestoreCtxInfo = NULL;
449}
450
451int CrBltEnter(PCR_BLITTER pBlitter, CR_BLITTER_CONTEXT *pRestoreCtxInfo, CR_BLITTER_WINDOW *pRestoreMural)
452{
453 if (!pBlitter->pCurrentMural)
454 {
455 crWarning("current mural not initialized!");
456 return VERR_INVALID_STATE;
457 }
458
459 if (CrBltIsEntered(pBlitter))
460 {
461 crWarning("blitter is entered already!");
462 return VERR_INVALID_STATE;
463 }
464
465 if (pRestoreCtxInfo)
466 {
467 pBlitter->pRestoreCtxInfo = pRestoreCtxInfo;
468 pBlitter->pRestoreMural = pRestoreMural;
469
470 pBlitter->pDispatch->Flush();
471 }
472 else
473 {
474 pBlitter->pRestoreCtxInfo = &pBlitter->CtxInfo;
475 }
476
477 pBlitter->pDispatch->MakeCurrent(pBlitter->pCurrentMural->Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
478
479 if (pBlitter->Flags.Initialized)
480 return VINF_SUCCESS;
481
482 int rc = crBltInitOnMakeCurent(pBlitter);
483 if (RT_SUCCESS(rc))
484 {
485 pBlitter->Flags.Initialized = 1;
486 return VINF_SUCCESS;
487 }
488
489 crWarning("crBltInitOnMakeCurent failed, rc %d", rc);
490 CrBltLeave(pBlitter);
491 return rc;
492}
493
494static void crBltBlitTexBuf(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, GLenum enmDstBuff, const PRTRECTSIZE pDstSize, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
495{
496 pBlitter->pDispatch->DrawBuffer(enmDstBuff);
497
498 crBltCheckSetupViewport(pBlitter, pDstSize, enmDstBuff == GL_DRAW_FRAMEBUFFER);
499
500 pBlitter->pfnBlt(pBlitter, pSrc, paSrcRects, pDstSize, paDstRects, cRects, fFlags & CRBLT_F_OFFSCREEN);
501}
502
503void CrBltBlitTexMural(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
504{
505 RTRECTSIZE DstSize = {pBlitter->pCurrentMural->width, pBlitter->pCurrentMural->height};
506
507 pBlitter->pDispatch->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
508
509 crBltBlitTexBuf(pBlitter, pSrc, paSrcRects, GL_BACK, &DstSize, paDstRects, cRects, fFlags & (~CRBLT_F_OFFSCREEN));
510}
511
512void CrBltBlitTexTex(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *pSrcRect, VBOXVR_TEXTURE *pDst, const RTRECT *pDstRect, uint32_t cRects, uint32_t fFlags)
513{
514 RTRECTSIZE DstSize = {(uint32_t)pDst->width, (uint32_t)pDst->height};
515
516 pBlitter->pDispatch->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, pBlitter->idFBO);
517
518 /* TODO: mag/min filters ? */
519
520 pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pDst->target, pDst->hwid, 0);
521
522// pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
523// pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
524
525 crBltBlitTexBuf(pBlitter, pSrc, pSrcRect, GL_DRAW_FRAMEBUFFER, &DstSize, pDstRect, cRects, fFlags);
526}
527
528void CrBltPresent(PCR_BLITTER pBlitter)
529{
530 if (pBlitter->CtxInfo.Base.visualBits & CR_DOUBLE_BIT)
531 pBlitter->pDispatch->SwapBuffers(pBlitter->pCurrentMural->Base.id, 0);
532 else
533 pBlitter->pDispatch->Flush();
534}
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