1 /*
2 * Copyright (c) 2007, 2008, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include "D3DPipeline.h"
27
28 #include "sun_java2d_d3d_D3DRenderer.h"
29
30 #include "D3DContext.h"
31 #include "D3DRenderer.h"
32 #include "D3DRenderQueue.h"
33
34 HRESULT D3DPIPELINE_API
D3DRenderer_DrawLine(D3DContext * d3dc,jint x1,jint y1,jint x2,jint y2)35 D3DRenderer_DrawLine(D3DContext *d3dc,
36 jint x1, jint y1, jint x2, jint y2)
37 {
38 J2dTraceLn4(J2D_TRACE_INFO,
39 "D3DRenderer_doDrawLineD3D x1=%-4d y1=%-4d x2=%-4d y2=%-4d",
40 x1, y1, x2, y2);
41 d3dc->BeginScene(STATE_RENDEROP);
42 return d3dc->pVCacher->DrawLine(x1, y1, x2, y2);
43 }
44
45 HRESULT D3DPIPELINE_API
D3DRenderer_DrawRect(D3DContext * d3dc,jint x,jint y,jint w,jint h)46 D3DRenderer_DrawRect(D3DContext *d3dc,
47 jint x, jint y, jint w, jint h)
48 {
49 J2dTraceLn4(J2D_TRACE_INFO,
50 "D3DRenderer_DrawRect x=%-4d y=%-4d w=%-4d h=%-4d",
51 x, y, w, h);
52
53 d3dc->BeginScene(STATE_RENDEROP);
54 return d3dc->pVCacher->DrawRect(x, y, x + w, y + h);
55 }
56
57 HRESULT D3DPIPELINE_API
D3DRenderer_FillRect(D3DContext * d3dc,jint x,jint y,jint w,jint h)58 D3DRenderer_FillRect(D3DContext *d3dc,
59 jint x, jint y, jint w, jint h)
60 {
61 J2dTraceLn4(J2D_TRACE_INFO,
62 "D3DRenderer_FillRect x=%-4d y=%-4d w=%-4d h=%-4d",
63 x, y, w, h);
64
65 d3dc->BeginScene(STATE_RENDEROP);
66 return d3dc->pVCacher->FillRect(x, y, x + w, y + h);
67 }
68
69 HRESULT D3DPIPELINE_API
D3DRenderer_DrawPoly(D3DContext * d3dc,jint nPoints,jboolean isClosed,jint transX,jint transY,jint * xPoints,jint * yPoints)70 D3DRenderer_DrawPoly(D3DContext *d3dc,
71 jint nPoints, jboolean isClosed,
72 jint transX, jint transY,
73 jint *xPoints, jint *yPoints)
74 {
75 J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_DrawPoly");
76
77 if (d3dc == NULL || xPoints == NULL || yPoints == NULL) {
78 J2dRlsTraceLn(J2D_TRACE_ERROR,
79 "D3DRenderer_DrawPoly: d3dc, xPoints or yPoints is NULL");
80 return E_FAIL;
81 }
82
83 d3dc->BeginScene(STATE_RENDEROP);
84 return d3dc->pVCacher->DrawPoly(nPoints, isClosed, transX, transY,
85 xPoints, yPoints);
86 }
87
88 HRESULT D3DPIPELINE_API
D3DRenderer_DrawScanlines(D3DContext * d3dc,jint scanlineCount,jint * scanlines)89 D3DRenderer_DrawScanlines(D3DContext *d3dc,
90 jint scanlineCount, jint *scanlines)
91 {
92 J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_DrawScanlines");
93
94 if (d3dc == NULL) {
95 return E_FAIL;
96 }
97 if (scanlines == NULL || scanlineCount <= 0) {
98 return D3D_OK;
99 }
100
101 d3dc->BeginScene(STATE_RENDEROP);
102 return d3dc->pVCacher->DrawScanlines(scanlineCount, scanlines);
103 }
104
105 HRESULT D3DPIPELINE_API
D3DRenderer_FillSpans(D3DContext * d3dc,jint spanCount,jint * spans)106 D3DRenderer_FillSpans(D3DContext *d3dc, jint spanCount, jint *spans)
107 {
108 J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_FillSpans");
109 if (d3dc == NULL) {
110 return E_FAIL;
111 }
112
113 d3dc->BeginScene(STATE_RENDEROP);
114 return d3dc->pVCacher->FillSpans(spanCount, spans);
115 }
116
117 HRESULT D3DPIPELINE_API
D3DRenderer_FillParallelogram(D3DContext * d3dc,jfloat fx11,jfloat fy11,jfloat dx21,jfloat dy21,jfloat dx12,jfloat dy12)118 D3DRenderer_FillParallelogram(D3DContext *d3dc,
119 jfloat fx11, jfloat fy11,
120 jfloat dx21, jfloat dy21,
121 jfloat dx12, jfloat dy12)
122 {
123 J2dTraceLn6(J2D_TRACE_INFO,
124 "D3DRenderer_FillParallelogram "
125 "x=%6.2f y=%6.2f "
126 "dx1=%6.2f dy1=%6.2f "
127 "dx2=%6.2f dy2=%6.2f ",
128 fx11, fy11,
129 dx21, dy21,
130 dx12, dy12);
131
132 d3dc->BeginScene(STATE_RENDEROP);
133 return d3dc->pVCacher->FillParallelogram(fx11, fy11,
134 dx21, dy21,
135 dx12, dy12);
136 }
137
138 HRESULT D3DPIPELINE_API
D3DRenderer_DrawParallelogram(D3DContext * d3dc,jfloat fx11,jfloat fy11,jfloat dx21,jfloat dy21,jfloat dx12,jfloat dy12,jfloat lwr21,jfloat lwr12)139 D3DRenderer_DrawParallelogram(D3DContext *d3dc,
140 jfloat fx11, jfloat fy11,
141 jfloat dx21, jfloat dy21,
142 jfloat dx12, jfloat dy12,
143 jfloat lwr21, jfloat lwr12)
144 {
145 HRESULT res;
146
147 J2dTraceLn8(J2D_TRACE_INFO,
148 "D3DRenderer_DrawParallelogram "
149 "x=%6.2f y=%6.2f "
150 "dx1=%6.2f dy1=%6.2f lwr1=%6.2f "
151 "dx2=%6.2f dy2=%6.2f lwr2=%6.2f ",
152 fx11, fy11,
153 dx21, dy21, lwr21,
154 dx12, dy12, lwr12);
155
156 // dx,dy for line width in the "21" and "12" directions.
157 jfloat ldx21 = dx21 * lwr21;
158 jfloat ldy21 = dy21 * lwr21;
159 jfloat ldx12 = dx12 * lwr12;
160 jfloat ldy12 = dy12 * lwr12;
161
162 // calculate origin of the outer parallelogram
163 jfloat ox11 = fx11 - (ldx21 + ldx12) / 2.0f;
164 jfloat oy11 = fy11 - (ldy21 + ldy12) / 2.0f;
165
166 res = d3dc->BeginScene(STATE_RENDEROP);
167 RETURN_STATUS_IF_FAILED(res);
168
169 // Only need to generate 4 quads if the interior still
170 // has a hole in it (i.e. if the line width ratio was
171 // less than 1.0)
172 if (lwr21 < 1.0f && lwr12 < 1.0f) {
173 // Note: "TOP", "BOTTOM", "LEFT" and "RIGHT" here are
174 // relative to whether the dxNN variables are positive
175 // and negative. The math works fine regardless of
176 // their signs, but for conceptual simplicity the
177 // comments will refer to the sides as if the dxNN
178 // were all positive. "TOP" and "BOTTOM" segments
179 // are defined by the dxy21 deltas. "LEFT" and "RIGHT"
180 // segments are defined by the dxy12 deltas.
181
182 // Each segment includes its starting corner and comes
183 // to just short of the following corner. Thus, each
184 // corner is included just once and the only lengths
185 // needed are the original parallelogram delta lengths
186 // and the "line width deltas". The sides will cover
187 // the following relative territories:
188 //
189 // T T T T T R
190 // L R
191 // L R
192 // L R
193 // L R
194 // L B B B B B
195
196 // TOP segment, to left side of RIGHT edge
197 // "width" of original pgram, "height" of hor. line size
198 fx11 = ox11;
199 fy11 = oy11;
200 res = d3dc->pVCacher->FillParallelogram(fx11, fy11,
201 dx21, dy21,
202 ldx12, ldy12);
203
204 // RIGHT segment, to top of BOTTOM edge
205 // "width" of vert. line size , "height" of original pgram
206 fx11 = ox11 + dx21;
207 fy11 = oy11 + dy21;
208 res = d3dc->pVCacher->FillParallelogram(fx11, fy11,
209 ldx21, ldy21,
210 dx12, dy12);
211
212 // BOTTOM segment, from right side of LEFT edge
213 // "width" of original pgram, "height" of hor. line size
214 fx11 = ox11 + dx12 + ldx21;
215 fy11 = oy11 + dy12 + ldy21;
216 res = d3dc->pVCacher->FillParallelogram(fx11, fy11,
217 dx21, dy21,
218 ldx12, ldy12);
219
220 // LEFT segment, from bottom of TOP edge
221 // "width" of vert. line size , "height" of inner pgram
222 fx11 = ox11 + ldx12;
223 fy11 = oy11 + ldy12;
224 res = d3dc->pVCacher->FillParallelogram(fx11, fy11,
225 ldx21, ldy21,
226 dx12, dy12);
227 } else {
228 // The line width ratios were large enough to consume
229 // the entire hole in the middle of the parallelogram
230 // so we can just issue one large quad for the outer
231 // parallelogram.
232 dx21 += ldx21;
233 dy21 += ldy21;
234 dx12 += ldx12;
235 dy12 += ldy12;
236
237 res = d3dc->pVCacher->FillParallelogram(ox11, oy11,
238 dx21, dy21,
239 dx12, dy12);
240 }
241
242 return res;
243 }
244
245 HRESULT D3DPIPELINE_API
D3DRenderer_FillAAParallelogram(D3DContext * d3dc,jfloat fx11,jfloat fy11,jfloat dx21,jfloat dy21,jfloat dx12,jfloat dy12)246 D3DRenderer_FillAAParallelogram(D3DContext *d3dc,
247 jfloat fx11, jfloat fy11,
248 jfloat dx21, jfloat dy21,
249 jfloat dx12, jfloat dy12)
250 {
251 IDirect3DDevice9 *pd3dDevice;
252 HRESULT res;
253
254 J2dTraceLn6(J2D_TRACE_INFO,
255 "D3DRenderer_FillAAParallelogram "
256 "x=%6.2f y=%6.2f "
257 "dx1=%6.2f dy1=%6.2f "
258 "dx2=%6.2f dy2=%6.2f ",
259 fx11, fy11,
260 dx21, dy21,
261 dx12, dy12);
262
263 res = d3dc->BeginScene(STATE_AAPGRAMOP);
264 RETURN_STATUS_IF_FAILED(res);
265
266 pd3dDevice = d3dc->Get3DDevice();
267 if (pd3dDevice == NULL) {
268 return E_FAIL;
269 }
270
271 res = d3dc->pVCacher->FillParallelogramAA(fx11, fy11,
272 dx21, dy21,
273 dx12, dy12);
274 return res;
275 }
276
277 HRESULT D3DPIPELINE_API
D3DRenderer_DrawAAParallelogram(D3DContext * d3dc,jfloat fx11,jfloat fy11,jfloat dx21,jfloat dy21,jfloat dx12,jfloat dy12,jfloat lwr21,jfloat lwr12)278 D3DRenderer_DrawAAParallelogram(D3DContext *d3dc,
279 jfloat fx11, jfloat fy11,
280 jfloat dx21, jfloat dy21,
281 jfloat dx12, jfloat dy12,
282 jfloat lwr21, jfloat lwr12)
283 {
284 IDirect3DDevice9 *pd3dDevice;
285 // dx,dy for line width in the "21" and "12" directions.
286 jfloat ldx21, ldy21, ldx12, ldy12;
287 // parameters for "outer" parallelogram
288 jfloat ofx11, ofy11, odx21, ody21, odx12, ody12;
289 // parameters for "inner" parallelogram
290 jfloat ifx11, ify11, idx21, idy21, idx12, idy12;
291 HRESULT res;
292
293 J2dTraceLn8(J2D_TRACE_INFO,
294 "D3DRenderer_DrawAAParallelogram "
295 "x=%6.2f y=%6.2f "
296 "dx1=%6.2f dy1=%6.2f lwr1=%6.2f "
297 "dx2=%6.2f dy2=%6.2f lwr2=%6.2f ",
298 fx11, fy11,
299 dx21, dy21, lwr21,
300 dx12, dy12, lwr12);
301
302 res = d3dc->BeginScene(STATE_AAPGRAMOP);
303 RETURN_STATUS_IF_FAILED(res);
304
305 pd3dDevice = d3dc->Get3DDevice();
306 if (pd3dDevice == NULL) {
307 return E_FAIL;
308 }
309
310 // calculate true dx,dy for line widths from the "line width ratios"
311 ldx21 = dx21 * lwr21;
312 ldy21 = dy21 * lwr21;
313 ldx12 = dx12 * lwr12;
314 ldy12 = dy12 * lwr12;
315
316 // calculate coordinates of the outer parallelogram
317 ofx11 = fx11 - (ldx21 + ldx12) / 2.0f;
318 ofy11 = fy11 - (ldy21 + ldy12) / 2.0f;
319 odx21 = dx21 + ldx21;
320 ody21 = dy21 + ldy21;
321 odx12 = dx12 + ldx12;
322 ody12 = dy12 + ldy12;
323
324 // Only process the inner parallelogram if the line width ratio
325 // did not consume the entire interior of the parallelogram
326 // (i.e. if the width ratio was less than 1.0)
327 if (lwr21 < 1.0f && lwr12 < 1.0f) {
328 // calculate coordinates of the inner parallelogram
329 ifx11 = fx11 + (ldx21 + ldx12) / 2.0f;
330 ify11 = fy11 + (ldy21 + ldy12) / 2.0f;
331 idx21 = dx21 - ldx21;
332 idy21 = dy21 - ldy21;
333 idx12 = dx12 - ldx12;
334 idy12 = dy12 - ldy12;
335
336 res = d3dc->pVCacher->DrawParallelogramAA(ofx11, ofy11,
337 odx21, ody21,
338 odx12, ody12,
339 ifx11, ify11,
340 idx21, idy21,
341 idx12, idy12);
342 } else {
343 // Just invoke a regular fill on the outer parallelogram
344 res = d3dc->pVCacher->FillParallelogramAA(ofx11, ofy11,
345 odx21, ody21,
346 odx12, ody12);
347 }
348
349 return res;
350 }
351
352 #ifndef D3D_PPL_DLL
353
354 extern "C"
355 {
356
357 JNIEXPORT void JNICALL
Java_sun_java2d_d3d_D3DRenderer_drawPoly(JNIEnv * env,jobject d3dr,jintArray xpointsArray,jintArray ypointsArray,jint nPoints,jboolean isClosed,jint transX,jint transY)358 Java_sun_java2d_d3d_D3DRenderer_drawPoly
359 (JNIEnv *env, jobject d3dr,
360 jintArray xpointsArray, jintArray ypointsArray,
361 jint nPoints, jboolean isClosed,
362 jint transX, jint transY)
363 {
364 jint *xPoints, *yPoints;
365
366 J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_drawPoly");
367
368 xPoints = (jint *)env->GetPrimitiveArrayCritical(xpointsArray, NULL);
369 if (xPoints != NULL) {
370 yPoints = (jint *)env->GetPrimitiveArrayCritical(ypointsArray, NULL);
371 if (yPoints != NULL) {
372 D3DContext *d3dc = D3DRQ_GetCurrentContext();
373
374 D3DRenderer_DrawPoly(d3dc,
375 nPoints, isClosed,
376 transX, transY,
377 xPoints, yPoints);
378
379 if (d3dc != NULL) {
380 HRESULT res = d3dc->EndScene();
381 D3DRQ_MarkLostIfNeeded(res,
382 D3DRQ_GetCurrentDestination());
383 }
384 env->ReleasePrimitiveArrayCritical(ypointsArray, yPoints, JNI_ABORT);
385 }
386 env->ReleasePrimitiveArrayCritical(xpointsArray, xPoints, JNI_ABORT);
387 }
388 }
389
390 }
391
392 #endif // D3D_PPL_DLL
393