blob: 4b0b358e8adee339713b9537004a5020fb76af17 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26#include "sun_java2d_d3d_D3DRenderer.h"
27#include "sun_java2d_windows_DDRenderer.h"
28#include "Win32SurfaceData.h"
29
30#include <ddraw.h>
31
32#include "D3DUtils.h"
33#include "ddrawUtils.h"
34
35#include "j2d_md.h"
36#include "jlong.h"
37
38/*
39 * Class: sun_java2d_d3d_D3DRenderer
40 * Method: doDrawLineD3D
41 * Signature: (Lsun/java2d/SurfaceData;IIIII)Z
42 */
43JNIEXPORT jboolean JNICALL
44Java_sun_java2d_d3d_D3DRenderer_doDrawLineD3D
45 (JNIEnv *env, jobject d3dr,
46 jlong pData, jlong pCtx,
47 jint x1, jint y1, jint x2, jint y2)
48{
49 Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
50 D3DContext *d3dc = (D3DContext *)jlong_to_ptr(pCtx);
51 static J2D_XY_C_VERTEX lineVerts[] = {
52#ifdef USE_SINGLE_VERTEX_FORMAT
53 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
54 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
55#else
56 // x, y, z, color
57 { 0, 0, 0, 0x0 },
58 { 0, 0, 0, 0x0 },
59#endif // USE_SINGLE_VERTEX_FORMAT
60 };
61
62 J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_doDrawLineD3D");
63 J2dTraceLn4(J2D_TRACE_VERBOSE,
64 " x1=%-4d y1=%-4d x2=%-4d y2=%-4d",
65 x1, y1, x2, y2);
66 HRESULT res = DDERR_GENERIC;
67 if (d3dc != NULL) {
68 DDrawSurface *ddTargetSurface = d3dc->GetTargetSurface();
69 if (ddTargetSurface == NULL) {
70 return FALSE;
71 }
72 ddTargetSurface->GetExclusiveAccess();
73 d3dc->GetExclusiveAccess();
74
75 IDirect3DDevice7 *d3dDevice = d3dc->Get3DDevice();
76 if (d3dDevice == NULL) {
77 d3dc->ReleaseExclusiveAccess();
78 ddTargetSurface->ReleaseExclusiveAccess();
79 return FALSE;
80 }
81
82 // +0.5f is needed to compensate for the -0.5f we
83 // force when setting the transform
84 lineVerts[0].x = (float)x1 + 0.5f;
85 lineVerts[0].y = (float)y1 + 0.5f;
86 lineVerts[0].color = d3dc->colorPixel;
87 lineVerts[1].x = (float)x2 + 0.5f;
88 lineVerts[1].y = (float)y2 + 0.5f;
89 lineVerts[1].color = d3dc->colorPixel;
90
91 D3DU_PRIM_LOOP_BEGIN(res, wsdo);
92 if (SUCCEEDED(res = d3dc->BeginScene(STATE_RENDEROP))) {
93 res = d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, D3DFVF_J2D_XY_C,
94 lineVerts, 2, 0);
95 // REMIND: need to be using the results of device testing
96 res = d3dDevice->DrawPrimitive(D3DPT_POINTLIST, D3DFVF_J2D_XY_C,
97 &(lineVerts[1]), 1, 0);
98 d3dc->EndScene(res);
99 }
100 D3DU_PRIM_LOOP_END(env, res, wsdo, "DrawPrimitive(D3DPT_LINESTRIP)");
101
102 d3dc->ReleaseExclusiveAccess();
103 ddTargetSurface->ReleaseExclusiveAccess();
104 }
105 return SUCCEEDED(res);
106}
107
108JNIEXPORT jboolean JNICALL
109Java_sun_java2d_d3d_D3DRenderer_doDrawRectD3D
110 (JNIEnv *env, jobject d3dr,
111 jlong pData, jlong pCtx,
112 jint x, jint y, jint w, jint h)
113{
114 Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
115 D3DContext *d3dc = (D3DContext *)jlong_to_ptr(pCtx);
116 float x1, y1, x2, y2;
117 static J2D_XY_C_VERTEX lineVerts[] = {
118#ifdef USE_SINGLE_VERTEX_FORMAT
119 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
120 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
121 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
122 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
123 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
124#else
125 // x, y, z, color
126 { 0, 0, 0, 0x0 },
127 { 0, 0, 0, 0x0 },
128 { 0, 0, 0, 0x0 },
129 { 0, 0, 0, 0x0 },
130 { 0, 0, 0, 0x0 },
131#endif // USE_SINGLE_VERTEX_FORMAT
132 };
133
134 J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_doDrawRectD3D");
135 J2dTraceLn4(J2D_TRACE_VERBOSE,
136 " x=%-4d y=%-4d w=%-4d h=%-4d",
137 x, y, w, h);
138
139 HRESULT res = DDERR_GENERIC;
140 if (d3dc != NULL) {
141 DDrawSurface *ddTargetSurface = d3dc->GetTargetSurface();
142 if (ddTargetSurface == NULL) {
143 return FALSE;
144 }
145 ddTargetSurface->GetExclusiveAccess();
146 d3dc->GetExclusiveAccess();
147
148 IDirect3DDevice7 *d3dDevice = d3dc->Get3DDevice();
149 if (d3dDevice == NULL) {
150 d3dc->ReleaseExclusiveAccess();
151 ddTargetSurface->ReleaseExclusiveAccess();
152 return FALSE;
153 }
154
155 // +0.5f is needed to compensate for the -0.5f we
156 // force when setting the transform
157 x1 = (float)x + 0.5f;
158 y1 = (float)y + 0.5f;
159 x2 = x1 + (float)w;
160 y2 = y1 + (float)h;
161 D3DU_INIT_VERTEX_PENT_XY(lineVerts, x1, y1, x2, y2);
162 D3DU_INIT_VERTEX_PENT_COLOR(lineVerts, d3dc->colorPixel);
163
164 D3DU_PRIM_LOOP_BEGIN(res, wsdo);
165 if (SUCCEEDED(res = d3dc->BeginScene(STATE_RENDEROP))) {
166 res = d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, D3DFVF_J2D_XY_C,
167 lineVerts, 5, 0);
168 d3dc->EndScene(res);
169 }
170 D3DU_PRIM_LOOP_END(env, res, wsdo, "DrawPrimitive(D3DPT_LINESTRIP)");
171
172 d3dc->ReleaseExclusiveAccess();
173 ddTargetSurface->ReleaseExclusiveAccess();
174 }
175 return SUCCEEDED(res);
176}
177
178/*
179 * Class: sun_java2d_d3d_D3DRenderer
180 * Method: doFillRectD3D
181 * Signature: (JIIII)Z
182 */
183JNIEXPORT jboolean JNICALL Java_sun_java2d_d3d_D3DRenderer_doFillRectD3D
184 (JNIEnv *env, jobject d3dr,
185 jlong pData, jlong pCtx,
186 jint x, jint y, jint w, jint h)
187{
188 Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
189 D3DContext *d3dc = (D3DContext *)jlong_to_ptr(pCtx);
190 HRESULT res = DDERR_GENERIC;
191 float x1, y1, x2, y2;
192 static J2D_XY_C_VERTEX quadVerts[] = {
193#ifdef USE_SINGLE_VERTEX_FORMAT
194 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
195 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
196 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
197 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f }
198#else
199 // x, y, z, color
200 { 0, 0, 0, 0x0 },
201 { 0, 0, 0, 0x0 },
202 { 0, 0, 0, 0x0 },
203 { 0, 0, 0, 0x0 },
204#endif // USE_SINGLE_VERTEX_FORMAT
205 };
206
207 J2dTraceLn(J2D_TRACE_INFO, "doFillRectD3D");
208 J2dTraceLn4(J2D_TRACE_VERBOSE, " x=%-4d y=%-4d w=%-4d h=%-4d", x, y, w, h);
209
210 if (d3dc != NULL) {
211 DDrawSurface *ddTargetSurface = d3dc->GetTargetSurface();
212 if (ddTargetSurface == NULL) {
213 return FALSE;
214 }
215 ddTargetSurface->GetExclusiveAccess();
216 d3dc->GetExclusiveAccess();
217
218 IDirect3DDevice7 *d3dDevice = d3dc->Get3DDevice();
219 if (d3dDevice == NULL) {
220 d3dc->ReleaseExclusiveAccess();
221 ddTargetSurface->ReleaseExclusiveAccess();
222 return FALSE;
223 }
224
225 x1 = (float)x;
226 y1 = (float)y;
227 x2 = x1 + (float)w;
228 y2 = y1 + (float)h;
229 D3DU_INIT_VERTEX_QUAD_COLOR(quadVerts, d3dc->colorPixel);
230 D3DU_INIT_VERTEX_QUAD_XY(quadVerts, x1, y1, x2, y2);
231
232 D3DU_PRIM_LOOP_BEGIN(res, wsdo);
233 if (SUCCEEDED(res = d3dc->BeginScene(STATE_RENDEROP))) {
234 res = d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_J2D_XY_C,
235 quadVerts, 4, 0);
236 d3dc->EndScene(res);
237 }
238 D3DU_PRIM_LOOP_END(env, res, wsdo, "DrawPrimitive(D3DPT_TRIANGLEFAN)");
239
240 d3dc->ReleaseExclusiveAccess();
241 ddTargetSurface->ReleaseExclusiveAccess();
242 }
243 return SUCCEEDED(res);
244}
245
246/*
247 * Class: sun_java2d_d3d_D3DRenderer
248 * Method: doDrawPoly
249 * Signature: (JII[I[IIZ)V
250 */
251JNIEXPORT void JNICALL Java_sun_java2d_d3d_D3DRenderer_doDrawPoly
252 (JNIEnv *env, jobject d3dr,
253 jlong pData, jlong pCtx,
254 jint transx, jint transy,
255 jintArray xcoordsArray, jintArray ycoordsArray, jint npoints,
256 jboolean needToClose)
257{
258 Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
259 D3DContext *d3dc = (D3DContext *)jlong_to_ptr(pCtx);
260 jint *xcoords, *ycoords;
261 jint i;
262
263 J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_doDrawPoly");
264 J2dTraceLn4(J2D_TRACE_VERBOSE,
265 " transx=%-4d transy=%-4d "\
266 "npoints=%-4d needToClose=%-4d",
267 transx, transy, npoints, needToClose);
268
269 if (d3dc == NULL) {
270 J2dTraceLn(J2D_TRACE_WARNING,
271 "D3DRenderer_doDrawPoly: null device context");
272 return;
273 }
274
275 if (JNU_IsNull(env, xcoordsArray) || JNU_IsNull(env, ycoordsArray)) {
276 JNU_ThrowNullPointerException(env, "coordinate array");
277 return;
278 }
279 if (env->GetArrayLength(ycoordsArray) < npoints ||
280 env->GetArrayLength(xcoordsArray) < npoints)
281 {
282 JNU_ThrowArrayIndexOutOfBoundsException(env, "coordinate array");
283 return;
284 }
285
286 xcoords = (jint *)
287 env->GetPrimitiveArrayCritical(xcoordsArray, NULL);
288 if (xcoords == NULL) {
289 return;
290 }
291
292 ycoords = (jint *)
293 env->GetPrimitiveArrayCritical(ycoordsArray, NULL);
294 if (ycoords == NULL) {
295 env->ReleasePrimitiveArrayCritical(xcoordsArray, xcoords, JNI_ABORT);
296 return;
297 }
298
299 DDrawSurface *ddTargetSurface = d3dc->GetTargetSurface();
300 if (ddTargetSurface == NULL) {
301 env->ReleasePrimitiveArrayCritical(ycoordsArray, ycoords, JNI_ABORT);
302 env->ReleasePrimitiveArrayCritical(xcoordsArray, xcoords, JNI_ABORT);
303 return;
304 }
305
306 ddTargetSurface->GetExclusiveAccess();
307 d3dc->GetExclusiveAccess();
308 IDirect3DDevice7 *d3dDevice = d3dc->Get3DDevice();
309 if (d3dDevice == NULL) {
310 d3dc->ReleaseExclusiveAccess();
311 ddTargetSurface->ReleaseExclusiveAccess();
312 env->ReleasePrimitiveArrayCritical(ycoordsArray, ycoords, JNI_ABORT);
313 env->ReleasePrimitiveArrayCritical(xcoordsArray, xcoords, JNI_ABORT);
314 return;
315 }
316
317 int totalPoints = npoints;
318 if (needToClose) {
319 if (xcoords[npoints - 1] != xcoords[0] ||
320 ycoords[npoints - 1] != ycoords[0])
321 {
322 totalPoints++;
323 } else {
324 needToClose = FALSE;
325 }
326 }
327 J2D_XY_C_VERTEX *lpVerts =
328 (J2D_XY_C_VERTEX *)safe_Malloc(totalPoints*sizeof(J2D_XY_C_VERTEX));
329 if (!lpVerts) {
330 d3dc->ReleaseExclusiveAccess();
331 ddTargetSurface->ReleaseExclusiveAccess();
332 env->ReleasePrimitiveArrayCritical(ycoordsArray, ycoords, JNI_ABORT);
333 env->ReleasePrimitiveArrayCritical(xcoordsArray, xcoords, JNI_ABORT);
334 return;
335 }
336
337 ZeroMemory(lpVerts, totalPoints*sizeof(J2D_XY_C_VERTEX));
338 for (i = 0; i < npoints; i++) {
339 // +0.5f is needed to compensate for the -0.5f we
340 // force when setting the transform
341 lpVerts[i].x = (float)(xcoords[i] + transx) + 0.5f;
342 lpVerts[i].y = (float)(ycoords[i] + transy) + 0.5f;
343 lpVerts[i].color = d3dc->colorPixel;
344 }
345 if (needToClose) {
346 lpVerts[npoints].x = (float)(xcoords[0] + transx) + 0.5f;
347 lpVerts[npoints].y = (float)(ycoords[0] + transy) + 0.5f;
348 lpVerts[npoints].color = d3dc->colorPixel;
349 }
350 env->ReleasePrimitiveArrayCritical(ycoordsArray, ycoords, JNI_ABORT);
351 env->ReleasePrimitiveArrayCritical(xcoordsArray, xcoords, JNI_ABORT);
352
353 HRESULT res;
354 D3DU_PRIM_LOOP_BEGIN(res, wsdo);
355 if (SUCCEEDED(res = d3dc->BeginScene(STATE_RENDEROP))) {
356 res = d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, D3DFVF_J2D_XY_C,
357 lpVerts, totalPoints, 0);
358 // REMIND: temp hack, need to be using the results of device testing
359 if (!needToClose) {
360 res = d3dDevice->DrawPrimitive(D3DPT_POINTLIST, D3DFVF_J2D_XY_C,
361 &(lpVerts[totalPoints-1]), 1, 0);
362 }
363 d3dc->EndScene(res);
364 }
365 D3DU_PRIM_LOOP_END(env, res, wsdo, "DrawPrimitive(D3DPT_LINESTRIP)");
366
367 free(lpVerts);
368
369 d3dc->ReleaseExclusiveAccess();
370 ddTargetSurface->ReleaseExclusiveAccess();
371}
372
373JNIEXPORT void JNICALL
374Java_sun_java2d_d3d_D3DRenderer_devFillSpans
375 (JNIEnv *env, jobject d3dr,
376 jlong pData, jlong pCtx,
377 jobject si, jlong pIterator, jint transx, jint transy)
378{
379 Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
380 D3DContext *d3dc = (D3DContext *)jlong_to_ptr(pCtx);
381 SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *)jlong_to_ptr(pIterator);
382 void *srData;
383 float x1, y1, x2, y2;
384 jint spanbox[4];
385 J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_devFillSpans");
386 J2dTraceLn2(J2D_TRACE_VERBOSE,
387 " transx=%-4d transy=%-4d", transx, transy);
388
389 if (JNU_IsNull(env, si)) {
390 JNU_ThrowNullPointerException(env, "span iterator");
391 return;
392 }
393 if (pFuncs == NULL) {
394 JNU_ThrowNullPointerException(env, "native iterator not supplied");
395 return;
396 }
397
398 if (d3dc == NULL) {
399 J2dTraceLn(J2D_TRACE_WARNING,
400 "D3DRenderer_devFillSpans: context is null");
401 return;
402 }
403
404 DDrawSurface *ddTargetSurface = d3dc->GetTargetSurface();
405 if (ddTargetSurface == NULL) {
406 return;
407 }
408
409 ddTargetSurface->GetExclusiveAccess();
410 d3dc->GetExclusiveAccess();
411
412 IDirect3DDevice7 *d3dDevice = d3dc->Get3DDevice();
413 if (d3dDevice == NULL) {
414 d3dc->ReleaseExclusiveAccess();
415 ddTargetSurface->ReleaseExclusiveAccess();
416 return;
417 }
418
419 HRESULT res = D3D_OK;
420
421 // buffer for the span vertexes (6 vertexes per span)
422 static J2DXYC_HEXA spanVx[MAX_CACHED_SPAN_VX_NUM];
423 J2DXYC_HEXA *pHexa = (J2DXYC_HEXA*)spanVx;
424 jint numOfCachedSpans = 0;
425
426 if (SUCCEEDED(res = d3dc->BeginScene(STATE_RENDEROP))) {
427 srData = (*pFuncs->open)(env, si);
428
429 // REMIND: this is wrong, if something has failed, we need to
430 // do a EndScene/BeginScene()
431 D3DU_PRIM_LOOP_BEGIN(res, wsdo);
432 while ((*pFuncs->nextSpan)(srData, spanbox)) {
433 x1 = (float)(spanbox[0] + transx);
434 y1 = (float)(spanbox[1] + transy);
435 x2 = (float)(spanbox[2] + transx);
436 y2 = (float)(spanbox[3] + transy);
437
438 D3DU_INIT_VERTEX_COLOR_6(*pHexa, d3dc->colorPixel);
439 D3DU_INIT_VERTEX_XY_6(*pHexa, x1, y1, x2, y2);
440 numOfCachedSpans++;
441 pHexa = (J2DXYC_HEXA*)PtrAddBytes(pHexa, sizeof(J2DXYC_HEXA));
442 if (numOfCachedSpans >= MAX_CACHED_SPAN_VX_NUM) {
443 if (FAILED(res = ddTargetSurface->IsLost())) {
444 numOfCachedSpans = 0;
445 break;
446 }
447
448 res = d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,
449 D3DFVF_J2D_XY_C,
450 (void*)spanVx,
451 6*numOfCachedSpans, 0);
452 numOfCachedSpans = 0;
453 pHexa = (J2DXYC_HEXA*)spanVx;
454 if (FAILED(res)) {
455 break;
456 }
457 }
458 }
459 if (numOfCachedSpans > 0) {
460 res = d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_J2D_XY_C,
461 (void*)spanVx,
462 6*numOfCachedSpans, 0);
463 }
464 D3DU_PRIM_LOOP_END(env, res, wsdo, "DrawPrimitive(D3DPT_TRIANGLEFAN)");
465
466 (*pFuncs->close)(env, srData);
467
468 d3dc->EndScene(res);
469 }
470
471 d3dc->ReleaseExclusiveAccess();
472 ddTargetSurface->ReleaseExclusiveAccess();
473}