blob: e174860718382e750d1011cf6d80f74154299f24 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-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 <stdlib.h>
27#include <jni.h>
28#include "ddrawUtils.h"
29#include "GraphicsPrimitiveMgr.h"
30#include "j2d_md.h"
31#include "jlong.h"
32
33#include "sun_java2d_d3d_D3DMaskFill.h"
34
35#include "Win32SurfaceData.h"
36
37#include "D3DContext.h"
38#include "D3DUtils.h"
39
40
41extern "C" {
42
43inline static HRESULT doMaskFill
44 (JNIEnv *env, jobject self,
45 Win32SDOps *wsdo, D3DContext *d3dc,
46 jint x, jint y, jint w, jint h,
47 jbyteArray maskArray,
48 jint maskoff, jint maskscan);
49
50
51JNIEXPORT void JNICALL
52Java_sun_java2d_d3d_D3DMaskFill_MaskFill
53 (JNIEnv *env, jobject self,
54 jlong pData, jlong pCtx,
55 jint x, jint y, jint w, jint h,
56 jbyteArray maskArray,
57 jint maskoff, jint maskscan)
58{
59 Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
60 D3DContext *d3dc = (D3DContext *)jlong_to_ptr(pCtx);
61
62 J2dTraceLn(J2D_TRACE_INFO, "D3DMaskFill_MaskFill");
63 J2dTraceLn4(J2D_TRACE_VERBOSE, " x=%-4d y=%-4d w=%-4d h=%-4d",
64 x, y, w, h);
65 J2dTraceLn2(J2D_TRACE_VERBOSE, " maskoff=%-4d maskscan=%-4d",
66 maskoff, maskscan);
67
68 if (d3dc == NULL || wsdo == NULL) {
69 J2dTraceLn(J2D_TRACE_WARNING,
70 "D3DMaskFill_MaskFill: context is null");
71 return;
72 }
73
74 HRESULT res;
75 D3D_EXEC_PRIM_LOOP(env, res, wsdo,
76 doMaskFill(env, self, wsdo, d3dc,
77 x, y, w, h,
78 maskArray, maskoff, maskscan));
79}
80
81inline static HRESULT doMaskFill
82 (JNIEnv *env, jobject self,
83 Win32SDOps *wsdo, D3DContext *d3dc,
84 jint x, jint y, jint w, jint h,
85 jbyteArray maskArray,
86 jint maskoff, jint maskscan)
87{
88 DXSurface *maskTexture;
89 static J2DLVERTEX quadVerts[4] = {
90 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
91 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
92 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f },
93 { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f }
94 };
95
96 DDrawSurface *ddTargetSurface = d3dc->GetTargetSurface();
97 if (ddTargetSurface == NULL) {
98 return DDERR_GENERIC;
99 }
100
101 ddTargetSurface->GetExclusiveAccess();
102 d3dc->GetExclusiveAccess();
103
104 IDirect3DDevice7 *d3dDevice = d3dc->Get3DDevice();
105
106 HRESULT res = D3D_OK;
107 if (maskArray) {
108 jubyte *pMask =
109 (jubyte*)env->GetPrimitiveArrayCritical(maskArray, 0);
110 float tx1, ty1, tx2, ty2;
111 jint tw, th, x0;
112 jint sx1, sy1, sx2, sy2;
113 jint sx, sy, sw, sh;
114
115 if (pMask == NULL) {
116 d3dc->ReleaseExclusiveAccess();
117 ddTargetSurface->ReleaseExclusiveAccess();
118 return DDERR_GENERIC;
119 }
120
121 maskTexture = d3dc->GetMaskTexture();
122 if (maskTexture == NULL ||
123 FAILED(res = d3dc->BeginScene(STATE_MASKOP)))
124 {
125 env->ReleasePrimitiveArrayCritical(maskArray, pMask, JNI_ABORT);
126 d3dc->ReleaseExclusiveAccess();
127 ddTargetSurface->ReleaseExclusiveAccess();
128 return DDERR_GENERIC;
129 }
130
131 if (FAILED(res = d3dc->SetTexture(maskTexture))) {
132 d3dc->EndScene(res);
133 env->ReleasePrimitiveArrayCritical(maskArray, pMask, JNI_ABORT);
134 d3dc->ReleaseExclusiveAccess();
135 ddTargetSurface->ReleaseExclusiveAccess();
136 return res;
137 }
138
139 x0 = x;
140 tx1 = 0.0f;
141 ty1 = 0.0f;
142 tw = D3DSD_MASK_TILE_SIZE;
143 th = D3DSD_MASK_TILE_SIZE;
144 sx1 = maskoff % maskscan;
145 sy1 = maskoff / maskscan;
146 sx2 = sx1 + w;
147 sy2 = sy1 + h;
148
149 D3DU_INIT_VERTEX_QUAD_COLOR(quadVerts, d3dc->colorPixel);
150 for (sy = sy1; (sy < sy2) && SUCCEEDED(res); sy += th, y += th) {
151 x = x0;
152 sh = ((sy + th) > sy2) ? (sy2 - sy) : th;
153
154 for (sx = sx1; (sx < sx2) && SUCCEEDED(res); sx += tw, x += tw) {
155 sw = ((sx + tw) > sx2) ? (sx2 - sx) : tw;
156
157 if (FAILED(d3dc->UploadImageToTexture(maskTexture,
158 pMask,
159 0, 0, sx, sy, sw, sh,
160 maskscan)))
161 {
162 continue;
163 }
164
165 // update the lower right texture coordinates
166 tx2 = ((float)sw) / tw;
167 ty2 = ((float)sh) / th;
168
169 D3DU_INIT_VERTEX_QUAD_XYUV(quadVerts,
170 (float)x, (float)y,
171 (float)(x+sw), (float)(y+sh),
172 tx1, ty1, tx2, ty2);
173 if (SUCCEEDED(res = ddTargetSurface->IsLost())) {
174 // render texture tile to the destination surface
175 res = d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,
176 D3DFVF_J2DLVERTEX,
177 quadVerts, 4, 0);
178 }
179
180 }
181 }
182
183 d3dc->EndScene(res);
184
185 env->ReleasePrimitiveArrayCritical(maskArray, pMask, JNI_ABORT);
186 } else {
187 float x1 = (float)x;
188 float y1 = (float)y;
189 float x2 = x1 + (float)w;
190 float y2 = y1 + (float)h;
191 D3DU_INIT_VERTEX_QUAD_COLOR(quadVerts, d3dc->colorPixel);
192 D3DU_INIT_VERTEX_QUAD_XY(quadVerts, x1, y1, x2, y2);
193 if (SUCCEEDED(res = d3dc->BeginScene(STATE_RENDEROP))) {
194 if (SUCCEEDED(res = ddTargetSurface->IsLost())) {
195 res = d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,
196 D3DFVF_J2DLVERTEX,
197 quadVerts, 4, 0);
198 }
199 d3dc->EndScene(res);
200 }
201 }
202
203 d3dc->ReleaseExclusiveAccess();
204 ddTargetSurface->ReleaseExclusiveAccess();
205
206 return res;
207}
208
209}