| /* | |
| * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. Oracle designates this | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| #include "D3DPipeline.h" | |
| #include "sun_java2d_d3d_D3DRenderer.h" | |
| #include "D3DContext.h" | |
| #include "D3DRenderer.h" | |
| #include "D3DRenderQueue.h" | |
| HRESULT | |
| D3DRenderer_DrawLine(D3DContext *d3dc, | |
| jint x1, jint y1, jint x2, jint y2) | |
| { | |
| J2dTraceLn4(J2D_TRACE_INFO, | |
| "D3DRenderer_doDrawLineD3D x1=%-4d y1=%-4d x2=%-4d y2=%-4d", | |
| x1, y1, x2, y2); | |
| d3dc->BeginScene(STATE_RENDEROP); | |
| return d3dc->pVCacher->DrawLine(x1, y1, x2, y2); | |
| } | |
| HRESULT | |
| D3DRenderer_DrawRect(D3DContext *d3dc, | |
| jint x, jint y, jint w, jint h) | |
| { | |
| J2dTraceLn4(J2D_TRACE_INFO, | |
| "D3DRenderer_DrawRect x=%-4d y=%-4d w=%-4d h=%-4d", | |
| x, y, w, h); | |
| d3dc->BeginScene(STATE_RENDEROP); | |
| return d3dc->pVCacher->DrawRect(x, y, x + w, y + h); | |
| } | |
| HRESULT | |
| D3DRenderer_FillRect(D3DContext *d3dc, | |
| jint x, jint y, jint w, jint h) | |
| { | |
| J2dTraceLn4(J2D_TRACE_INFO, | |
| "D3DRenderer_FillRect x=%-4d y=%-4d w=%-4d h=%-4d", | |
| x, y, w, h); | |
| d3dc->BeginScene(STATE_RENDEROP); | |
| return d3dc->pVCacher->FillRect(x, y, x + w, y + h); | |
| } | |
| HRESULT | |
| D3DRenderer_DrawPoly(D3DContext *d3dc, | |
| jint nPoints, jboolean isClosed, | |
| jint transX, jint transY, | |
| jint *xPoints, jint *yPoints) | |
| { | |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_DrawPoly"); | |
| if (d3dc == NULL || xPoints == NULL || yPoints == NULL) { | |
| J2dRlsTraceLn(J2D_TRACE_ERROR, | |
| "D3DRenderer_DrawPoly: d3dc, xPoints or yPoints is NULL"); | |
| return E_FAIL; | |
| } | |
| d3dc->BeginScene(STATE_RENDEROP); | |
| return d3dc->pVCacher->DrawPoly(nPoints, isClosed, transX, transY, | |
| xPoints, yPoints); | |
| } | |
| HRESULT | |
| D3DRenderer_DrawScanlines(D3DContext *d3dc, | |
| jint scanlineCount, jint *scanlines) | |
| { | |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_DrawScanlines"); | |
| if (d3dc == NULL) { | |
| return E_FAIL; | |
| } | |
| if (scanlines == NULL || scanlineCount <= 0) { | |
| return D3D_OK; | |
| } | |
| d3dc->BeginScene(STATE_RENDEROP); | |
| return d3dc->pVCacher->DrawScanlines(scanlineCount, scanlines); | |
| } | |
| HRESULT | |
| D3DRenderer_FillSpans(D3DContext *d3dc, jint spanCount, jint *spans) | |
| { | |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_FillSpans"); | |
| if (d3dc == NULL) { | |
| return E_FAIL; | |
| } | |
| d3dc->BeginScene(STATE_RENDEROP); | |
| return d3dc->pVCacher->FillSpans(spanCount, spans); | |
| } | |
| HRESULT | |
| D3DRenderer_FillParallelogram(D3DContext *d3dc, | |
| jfloat fx11, jfloat fy11, | |
| jfloat dx21, jfloat dy21, | |
| jfloat dx12, jfloat dy12) | |
| { | |
| J2dTraceLn6(J2D_TRACE_INFO, | |
| "D3DRenderer_FillParallelogram " | |
| "x=%6.2f y=%6.2f " | |
| "dx1=%6.2f dy1=%6.2f " | |
| "dx2=%6.2f dy2=%6.2f ", | |
| fx11, fy11, | |
| dx21, dy21, | |
| dx12, dy12); | |
| d3dc->BeginScene(STATE_RENDEROP); | |
| return d3dc->pVCacher->FillParallelogram(fx11, fy11, | |
| dx21, dy21, | |
| dx12, dy12); | |
| } | |
| HRESULT | |
| D3DRenderer_DrawParallelogram(D3DContext *d3dc, | |
| jfloat fx11, jfloat fy11, | |
| jfloat dx21, jfloat dy21, | |
| jfloat dx12, jfloat dy12, | |
| jfloat lwr21, jfloat lwr12) | |
| { | |
| HRESULT res; | |
| J2dTraceLn8(J2D_TRACE_INFO, | |
| "D3DRenderer_DrawParallelogram " | |
| "x=%6.2f y=%6.2f " | |
| "dx1=%6.2f dy1=%6.2f lwr1=%6.2f " | |
| "dx2=%6.2f dy2=%6.2f lwr2=%6.2f ", | |
| fx11, fy11, | |
| dx21, dy21, lwr21, | |
| dx12, dy12, lwr12); | |
| // dx,dy for line width in the "21" and "12" directions. | |
| jfloat ldx21 = dx21 * lwr21; | |
| jfloat ldy21 = dy21 * lwr21; | |
| jfloat ldx12 = dx12 * lwr12; | |
| jfloat ldy12 = dy12 * lwr12; | |
| // calculate origin of the outer parallelogram | |
| jfloat ox11 = fx11 - (ldx21 + ldx12) / 2.0f; | |
| jfloat oy11 = fy11 - (ldy21 + ldy12) / 2.0f; | |
| res = d3dc->BeginScene(STATE_RENDEROP); | |
| RETURN_STATUS_IF_FAILED(res); | |
| // Only need to generate 4 quads if the interior still | |
| // has a hole in it (i.e. if the line width ratio was | |
| // less than 1.0) | |
| if (lwr21 < 1.0f && lwr12 < 1.0f) { | |
| // Note: "TOP", "BOTTOM", "LEFT" and "RIGHT" here are | |
| // relative to whether the dxNN variables are positive | |
| // and negative. The math works fine regardless of | |
| // their signs, but for conceptual simplicity the | |
| // comments will refer to the sides as if the dxNN | |
| // were all positive. "TOP" and "BOTTOM" segments | |
| // are defined by the dxy21 deltas. "LEFT" and "RIGHT" | |
| // segments are defined by the dxy12 deltas. | |
| // Each segment includes its starting corner and comes | |
| // to just short of the following corner. Thus, each | |
| // corner is included just once and the only lengths | |
| // needed are the original parallelogram delta lengths | |
| // and the "line width deltas". The sides will cover | |
| // the following relative territories: | |
| // | |
| // T T T T T R | |
| // L R | |
| // L R | |
| // L R | |
| // L R | |
| // L B B B B B | |
| // TOP segment, to left side of RIGHT edge | |
| // "width" of original pgram, "height" of hor. line size | |
| fx11 = ox11; | |
| fy11 = oy11; | |
| res = d3dc->pVCacher->FillParallelogram(fx11, fy11, | |
| dx21, dy21, | |
| ldx12, ldy12); | |
| // RIGHT segment, to top of BOTTOM edge | |
| // "width" of vert. line size , "height" of original pgram | |
| fx11 = ox11 + dx21; | |
| fy11 = oy11 + dy21; | |
| res = d3dc->pVCacher->FillParallelogram(fx11, fy11, | |
| ldx21, ldy21, | |
| dx12, dy12); | |
| // BOTTOM segment, from right side of LEFT edge | |
| // "width" of original pgram, "height" of hor. line size | |
| fx11 = ox11 + dx12 + ldx21; | |
| fy11 = oy11 + dy12 + ldy21; | |
| res = d3dc->pVCacher->FillParallelogram(fx11, fy11, | |
| dx21, dy21, | |
| ldx12, ldy12); | |
| // LEFT segment, from bottom of TOP edge | |
| // "width" of vert. line size , "height" of inner pgram | |
| fx11 = ox11 + ldx12; | |
| fy11 = oy11 + ldy12; | |
| res = d3dc->pVCacher->FillParallelogram(fx11, fy11, | |
| ldx21, ldy21, | |
| dx12, dy12); | |
| } else { | |
| // The line width ratios were large enough to consume | |
| // the entire hole in the middle of the parallelogram | |
| // so we can just issue one large quad for the outer | |
| // parallelogram. | |
| dx21 += ldx21; | |
| dy21 += ldy21; | |
| dx12 += ldx12; | |
| dy12 += ldy12; | |
| res = d3dc->pVCacher->FillParallelogram(ox11, oy11, | |
| dx21, dy21, | |
| dx12, dy12); | |
| } | |
| return res; | |
| } | |
| HRESULT | |
| D3DRenderer_FillAAParallelogram(D3DContext *d3dc, | |
| jfloat fx11, jfloat fy11, | |
| jfloat dx21, jfloat dy21, | |
| jfloat dx12, jfloat dy12) | |
| { | |
| IDirect3DDevice9 *pd3dDevice; | |
| HRESULT res; | |
| J2dTraceLn6(J2D_TRACE_INFO, | |
| "D3DRenderer_FillAAParallelogram " | |
| "x=%6.2f y=%6.2f " | |
| "dx1=%6.2f dy1=%6.2f " | |
| "dx2=%6.2f dy2=%6.2f ", | |
| fx11, fy11, | |
| dx21, dy21, | |
| dx12, dy12); | |
| res = d3dc->BeginScene(STATE_AAPGRAMOP); | |
| RETURN_STATUS_IF_FAILED(res); | |
| pd3dDevice = d3dc->Get3DDevice(); | |
| if (pd3dDevice == NULL) { | |
| return E_FAIL; | |
| } | |
| res = d3dc->pVCacher->FillParallelogramAA(fx11, fy11, | |
| dx21, dy21, | |
| dx12, dy12); | |
| return res; | |
| } | |
| HRESULT | |
| D3DRenderer_DrawAAParallelogram(D3DContext *d3dc, | |
| jfloat fx11, jfloat fy11, | |
| jfloat dx21, jfloat dy21, | |
| jfloat dx12, jfloat dy12, | |
| jfloat lwr21, jfloat lwr12) | |
| { | |
| IDirect3DDevice9 *pd3dDevice; | |
| // dx,dy for line width in the "21" and "12" directions. | |
| jfloat ldx21, ldy21, ldx12, ldy12; | |
| // parameters for "outer" parallelogram | |
| jfloat ofx11, ofy11, odx21, ody21, odx12, ody12; | |
| // parameters for "inner" parallelogram | |
| jfloat ifx11, ify11, idx21, idy21, idx12, idy12; | |
| HRESULT res; | |
| J2dTraceLn8(J2D_TRACE_INFO, | |
| "D3DRenderer_DrawAAParallelogram " | |
| "x=%6.2f y=%6.2f " | |
| "dx1=%6.2f dy1=%6.2f lwr1=%6.2f " | |
| "dx2=%6.2f dy2=%6.2f lwr2=%6.2f ", | |
| fx11, fy11, | |
| dx21, dy21, lwr21, | |
| dx12, dy12, lwr12); | |
| res = d3dc->BeginScene(STATE_AAPGRAMOP); | |
| RETURN_STATUS_IF_FAILED(res); | |
| pd3dDevice = d3dc->Get3DDevice(); | |
| if (pd3dDevice == NULL) { | |
| return E_FAIL; | |
| } | |
| // calculate true dx,dy for line widths from the "line width ratios" | |
| ldx21 = dx21 * lwr21; | |
| ldy21 = dy21 * lwr21; | |
| ldx12 = dx12 * lwr12; | |
| ldy12 = dy12 * lwr12; | |
| // calculate coordinates of the outer parallelogram | |
| ofx11 = fx11 - (ldx21 + ldx12) / 2.0f; | |
| ofy11 = fy11 - (ldy21 + ldy12) / 2.0f; | |
| odx21 = dx21 + ldx21; | |
| ody21 = dy21 + ldy21; | |
| odx12 = dx12 + ldx12; | |
| ody12 = dy12 + ldy12; | |
| // Only process the inner parallelogram if the line width ratio | |
| // did not consume the entire interior of the parallelogram | |
| // (i.e. if the width ratio was less than 1.0) | |
| if (lwr21 < 1.0f && lwr12 < 1.0f) { | |
| // calculate coordinates of the inner parallelogram | |
| ifx11 = fx11 + (ldx21 + ldx12) / 2.0f; | |
| ify11 = fy11 + (ldy21 + ldy12) / 2.0f; | |
| idx21 = dx21 - ldx21; | |
| idy21 = dy21 - ldy21; | |
| idx12 = dx12 - ldx12; | |
| idy12 = dy12 - ldy12; | |
| res = d3dc->pVCacher->DrawParallelogramAA(ofx11, ofy11, | |
| odx21, ody21, | |
| odx12, ody12, | |
| ifx11, ify11, | |
| idx21, idy21, | |
| idx12, idy12); | |
| } else { | |
| // Just invoke a regular fill on the outer parallelogram | |
| res = d3dc->pVCacher->FillParallelogramAA(ofx11, ofy11, | |
| odx21, ody21, | |
| odx12, ody12); | |
| } | |
| return res; | |
| } | |
| extern "C" | |
| { | |
| 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) | |
| { | |
| jint *xPoints, *yPoints; | |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRenderer_drawPoly"); | |
| xPoints = (jint *)env->GetPrimitiveArrayCritical(xpointsArray, NULL); | |
| if (xPoints != NULL) { | |
| yPoints = (jint *)env->GetPrimitiveArrayCritical(ypointsArray, NULL); | |
| if (yPoints != NULL) { | |
| D3DContext *d3dc = D3DRQ_GetCurrentContext(); | |
| D3DRenderer_DrawPoly(d3dc, | |
| nPoints, isClosed, | |
| transX, transY, | |
| xPoints, yPoints); | |
| if (d3dc != NULL) { | |
| HRESULT res = d3dc->EndScene(); | |
| D3DRQ_MarkLostIfNeeded(res, | |
| D3DRQ_GetCurrentDestination()); | |
| } | |
| env->ReleasePrimitiveArrayCritical(ypointsArray, yPoints, JNI_ABORT); | |
| } | |
| env->ReleasePrimitiveArrayCritical(xpointsArray, xPoints, JNI_ABORT); | |
| } | |
| } | |
| } |