author | chegar |
Thu, 17 Oct 2019 20:54:25 +0100 | |
branch | datagramsocketimpl-branch |
changeset 58679 | 9c3209ff7550 |
parent 58678 | 9cf78a70fa4f |
parent 58626 | a9ed3d93cca3 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
58324
0aba35254e00
8229896: Delete an unused code in the BufferedContext
serb
parents:
47216
diff
changeset
|
2 |
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. |
2 | 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 |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 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 |
* |
|
5506 | 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. |
|
2 | 24 |
*/ |
25 |
||
887 | 26 |
#include "D3DPipeline.h" |
2 | 27 |
#include "jlong.h" |
28 |
||
29 |
#include "GraphicsPrimitiveMgr.h" |
|
887 | 30 |
#include "D3DContext.h" |
2 | 31 |
#include "D3DSurfaceData.h" |
887 | 32 |
#include "D3DBufImgOps.h" |
33 |
#include "D3DPaints.h" |
|
34 |
#include "D3DRenderQueue.h" |
|
35 |
#include "D3DShaders.h" |
|
36 |
#include "D3DTextRenderer.h" |
|
37 |
#include "D3DPipelineManager.h" |
|
38 |
#include "D3DGlyphCache.h" |
|
2 | 39 |
|
40 |
typedef struct { |
|
41 |
D3DBLEND src; |
|
42 |
D3DBLEND dst; |
|
43 |
} D3DBlendRule; |
|
44 |
||
45 |
/** |
|
46 |
* This table contains the standard blending rules (or Porter-Duff compositing |
|
47 |
* factors) used in SetRenderState(), indexed by the rule constants from the |
|
48 |
* AlphaComposite class. |
|
49 |
*/ |
|
50 |
D3DBlendRule StdBlendRules[] = { |
|
51 |
{ D3DBLEND_ZERO, D3DBLEND_ZERO }, /* 0 - Nothing */ |
|
52 |
{ D3DBLEND_ZERO, D3DBLEND_ZERO }, /* 1 - RULE_Clear */ |
|
53 |
{ D3DBLEND_ONE, D3DBLEND_ZERO }, /* 2 - RULE_Src */ |
|
54 |
{ D3DBLEND_ONE, D3DBLEND_INVSRCALPHA }, /* 3 - RULE_SrcOver */ |
|
55 |
{ D3DBLEND_INVDESTALPHA, D3DBLEND_ONE }, /* 4 - RULE_DstOver */ |
|
56 |
{ D3DBLEND_DESTALPHA, D3DBLEND_ZERO }, /* 5 - RULE_SrcIn */ |
|
57 |
{ D3DBLEND_ZERO, D3DBLEND_SRCALPHA }, /* 6 - RULE_DstIn */ |
|
58 |
{ D3DBLEND_INVDESTALPHA, D3DBLEND_ZERO }, /* 7 - RULE_SrcOut */ |
|
59 |
{ D3DBLEND_ZERO, D3DBLEND_INVSRCALPHA }, /* 8 - RULE_DstOut */ |
|
60 |
{ D3DBLEND_ZERO, D3DBLEND_ONE }, /* 9 - RULE_Dst */ |
|
61 |
{ D3DBLEND_DESTALPHA, D3DBLEND_INVSRCALPHA }, /*10 - RULE_SrcAtop */ |
|
62 |
{ D3DBLEND_INVDESTALPHA, D3DBLEND_SRCALPHA }, /*11 - RULE_DstAtop */ |
|
63 |
{ D3DBLEND_INVDESTALPHA, D3DBLEND_INVSRCALPHA }, /*12 - RULE_AlphaXor*/ |
|
64 |
}; |
|
65 |
||
887 | 66 |
void |
67 |
D3DUtils_SetOrthoMatrixOffCenterLH(D3DMATRIX *m, |
|
68 |
float width, float height) |
|
69 |
{ |
|
70 |
ZeroMemory(m, sizeof(D3DMATRIX)); |
|
71 |
m->_11 = 2.0f/width; |
|
72 |
m->_22 = -2.0f/height; |
|
73 |
m->_33 = 0.5f; |
|
74 |
m->_44 = 1.0f; |
|
75 |
||
76 |
m->_41 = -1.0f; |
|
77 |
m->_42 = 1.0f; |
|
78 |
m->_43 = 0.5f; |
|
79 |
} |
|
80 |
||
81 |
void |
|
82 |
D3DUtils_SetIdentityMatrix(D3DMATRIX *m) |
|
2 | 83 |
{ |
887 | 84 |
m->_12 = m->_13 = m->_14 = m->_21 = m->_23 = m->_24 = 0.0f; |
85 |
m->_31 = m->_32 = m->_34 = m->_41 = m->_42 = m->_43 = 0.0f; |
|
86 |
m->_11 = m->_22 = m->_33 = m->_44 = 1.0f; |
|
87 |
} |
|
88 |
||
89 |
// the following methods are copies of the AffineTransform's class |
|
90 |
// corresponding methods, with these changes to the indexes: |
|
91 |
// 00 -> 11 |
|
92 |
// 11 -> 22 |
|
93 |
// 01 -> 21 |
|
94 |
// 10 -> 12 |
|
95 |
// 02 -> 41 |
|
96 |
// 12 -> 42 |
|
97 |
||
98 |
void |
|
99 |
D3DUtils_2DConcatenateM(D3DMATRIX *m, D3DMATRIX *m1) |
|
100 |
{ |
|
101 |
float M0, M1; |
|
102 |
float T00, T10, T01, T11; |
|
103 |
float T02, T12; |
|
104 |
||
105 |
T00 = m1->_11; T01 = m1->_21; T02 = m1->_41; |
|
106 |
T10 = m1->_12; T11 = m1->_22; T12 = m1->_42; |
|
107 |
||
108 |
M0 = m->_11; |
|
109 |
M1 = m->_21; |
|
110 |
m->_11 = T00 * M0 + T10 * M1; |
|
111 |
m->_21 = T01 * M0 + T11 * M1; |
|
112 |
m->_41 += T02 * M0 + T12 * M1; |
|
113 |
||
114 |
M0 = m->_12; |
|
115 |
M1 = m->_22; |
|
116 |
m->_12 = T00 * M0 + T10 * M1; |
|
117 |
m->_22 = T01 * M0 + T11 * M1; |
|
118 |
m->_42 += T02 * M0 + T12 * M1; |
|
2 | 119 |
} |
120 |
||
887 | 121 |
#ifdef UPDATE_TX |
122 |
||
123 |
void |
|
124 |
D3DUtils_2DScaleM(D3DMATRIX *m, float sx, float sy) |
|
125 |
{ |
|
126 |
m->_11 *= sx; |
|
127 |
m->_22 *= sy; |
|
128 |
} |
|
129 |
||
130 |
void |
|
131 |
D3DUtils_2DInvertM(D3DMATRIX *m) |
|
2 | 132 |
{ |
887 | 133 |
float M11, M21, M41; |
134 |
float M12, M22, M42; |
|
135 |
float det; |
|
2 | 136 |
|
887 | 137 |
M11 = m->_11; M21 = m->_21; M41 = m->_41; |
138 |
M12 = m->_12; M22 = m->_22; M42 = m->_42; |
|
139 |
det = M11 * M22 - M21 * M12; |
|
140 |
if (fabs(det) <= 0.0000000001f) { |
|
141 |
memset(m, 0, sizeof(D3DMATRIX)); |
|
142 |
return; |
|
143 |
} |
|
144 |
m->_11 = M22 / det; |
|
145 |
m->_12 = -M12 / det; |
|
146 |
m->_21 = -M21 / det; |
|
147 |
m->_22 = M11 / det; |
|
148 |
m->_41 = (M21 * M42 - M22 * M41) / det; |
|
149 |
m->_42 = (M12 * M41 - M11 * M42) / det; |
|
150 |
} |
|
2 | 151 |
|
887 | 152 |
void |
153 |
D3DUtils_2DTranslateM(D3DMATRIX *m, float tx, float ty) |
|
154 |
{ |
|
155 |
m->_41 = tx * m->_11 + ty * m->_21 + m->_41; |
|
156 |
m->_42 = tx * m->_12 + ty * m->_22 + m->_42; |
|
157 |
} |
|
158 |
||
159 |
void |
|
160 |
D3DUtils_2DTransformXY(D3DMATRIX *m, float *px, float *py) |
|
161 |
{ |
|
162 |
float x = *px; |
|
163 |
float y = *py; |
|
164 |
||
165 |
*px = x * m->_11 + y * m->_21 + m->_41; |
|
166 |
*py = x * m->_12 + y * m->_22 + m->_42; |
|
167 |
} |
|
168 |
||
169 |
void |
|
170 |
D3DUtils_2DInverseTransformXY(D3DMATRIX *m, float *px, float *py) |
|
171 |
{ |
|
172 |
float x = *px, y = *py; |
|
173 |
||
174 |
x -= m->_41; |
|
175 |
y -= m->_42; |
|
176 |
||
177 |
float det = m->_11 * m->_22 - m->_21 * m->_12; |
|
178 |
if (fabs(det) < 0.0000000001f) { |
|
179 |
*px = 0.0f; |
|
180 |
*py = 0.0f; |
|
2 | 181 |
} else { |
887 | 182 |
*px = (x * m->_22 - y * m->_21) / det; |
183 |
*py = (y * m->_11 - x * m->_12) / det; |
|
2 | 184 |
} |
185 |
} |
|
186 |
||
887 | 187 |
#endif // UPDATE_TX |
188 |
||
189 |
static void |
|
190 |
D3DContext_DisposeShader(jlong programID) |
|
191 |
{ |
|
192 |
IDirect3DPixelShader9 *shader = |
|
193 |
(IDirect3DPixelShader9 *)jlong_to_ptr(programID); |
|
194 |
||
195 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext_DisposeShader"); |
|
196 |
||
197 |
SAFE_RELEASE(shader); |
|
198 |
} |
|
199 |
||
200 |
// static |
|
201 |
HRESULT |
|
202 |
D3DContext::CreateInstance(IDirect3D9 *pd3d9, UINT adapter, D3DContext **ppCtx) |
|
203 |
{ |
|
204 |
HRESULT res; |
|
205 |
*ppCtx = new D3DContext(pd3d9, adapter); |
|
206 |
if (FAILED(res = (*ppCtx)->InitContext())) { |
|
207 |
delete *ppCtx; |
|
208 |
*ppCtx = NULL; |
|
209 |
} |
|
210 |
return res; |
|
211 |
} |
|
2 | 212 |
|
887 | 213 |
D3DContext::D3DContext(IDirect3D9 *pd3d, UINT adapter) |
214 |
{ |
|
215 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::D3DContext"); |
|
216 |
J2dTraceLn1(J2D_TRACE_VERBOSE, " pd3d=0x%x", pd3d); |
|
217 |
pd3dObject = pd3d; |
|
218 |
pd3dDevice = NULL; |
|
219 |
adapterOrdinal = adapter; |
|
220 |
||
221 |
pResourceMgr = NULL; |
|
222 |
pMaskCache = NULL; |
|
223 |
pVCacher = NULL; |
|
224 |
||
225 |
pSyncQuery = NULL; |
|
226 |
pSyncRTRes = NULL; |
|
227 |
pStateBlock = NULL; |
|
2 | 228 |
|
887 | 229 |
D3DC_INIT_SHADER_LIST(convolvePrograms, MAX_CONVOLVE); |
230 |
D3DC_INIT_SHADER_LIST(rescalePrograms, MAX_RESCALE); |
|
231 |
D3DC_INIT_SHADER_LIST(lookupPrograms, MAX_LOOKUP); |
|
232 |
D3DC_INIT_SHADER_LIST(basicGradPrograms, 4); |
|
233 |
D3DC_INIT_SHADER_LIST(linearGradPrograms, 8); |
|
234 |
D3DC_INIT_SHADER_LIST(radialGradPrograms, 8); |
|
235 |
||
236 |
pLCDGlyphCache= NULL; |
|
237 |
pGrayscaleGlyphCache= NULL; |
|
238 |
lcdTextProgram = NULL; |
|
239 |
aaPgramProgram = NULL; |
|
240 |
||
241 |
contextCaps = CAPS_EMPTY; |
|
242 |
bBeginScenePending = FALSE; |
|
243 |
||
244 |
ZeroMemory(&devCaps, sizeof(D3DCAPS9)); |
|
245 |
ZeroMemory(&curParams, sizeof(curParams)); |
|
246 |
||
247 |
extraAlpha = 1.0f; |
|
2 | 248 |
} |
249 |
||
887 | 250 |
void D3DContext::ReleaseDefPoolResources() |
251 |
{ |
|
252 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::ReleaseDefPoolResources"); |
|
2 | 253 |
|
887 | 254 |
EndScene(); |
2 | 255 |
|
887 | 256 |
contextCaps = CAPS_EMPTY; |
2 | 257 |
|
887 | 258 |
SAFE_RELEASE(pSyncQuery); |
259 |
SAFE_RELEASE(pStateBlock); |
|
2 | 260 |
|
887 | 261 |
if (pVCacher != NULL) { |
262 |
pVCacher->ReleaseDefPoolResources(); |
|
263 |
} |
|
264 |
if (pMaskCache != NULL) { |
|
265 |
pMaskCache->ReleaseDefPoolResources(); |
|
266 |
} |
|
267 |
if (pLCDGlyphCache != NULL) { |
|
268 |
pLCDGlyphCache->ReleaseDefPoolResources(); |
|
2 | 269 |
} |
887 | 270 |
if (pGrayscaleGlyphCache != NULL) { |
271 |
pGrayscaleGlyphCache->ReleaseDefPoolResources(); |
|
272 |
} |
|
273 |
if (pResourceMgr != NULL) { |
|
274 |
if (pSyncRTRes != NULL) { |
|
275 |
pResourceMgr->ReleaseResource(pSyncRTRes); |
|
276 |
pSyncRTRes = NULL; |
|
277 |
} |
|
278 |
pResourceMgr->ReleaseDefPoolResources(); |
|
279 |
} |
|
280 |
ZeroMemory(lastTexture, sizeof(lastTexture)); |
|
281 |
ZeroMemory(lastTextureColorState, sizeof(lastTextureColorState)); |
|
282 |
} |
|
2 | 283 |
|
887 | 284 |
void D3DContext::ReleaseContextResources() |
285 |
{ |
|
286 |
J2dTraceLn1(J2D_TRACE_INFO, |
|
287 |
"D3DContext::ReleaseContextResources: pd3dDevice = 0x%x", |
|
288 |
pd3dDevice); |
|
289 |
||
290 |
ReleaseDefPoolResources(); |
|
291 |
||
292 |
// dispose shader lists |
|
293 |
ShaderList_Dispose(&convolvePrograms); |
|
294 |
ShaderList_Dispose(&rescalePrograms); |
|
295 |
ShaderList_Dispose(&lookupPrograms); |
|
296 |
ShaderList_Dispose(&basicGradPrograms); |
|
297 |
ShaderList_Dispose(&linearGradPrograms); |
|
298 |
ShaderList_Dispose(&radialGradPrograms); |
|
299 |
||
300 |
SAFE_DELETE(pLCDGlyphCache); |
|
301 |
SAFE_DELETE(pGrayscaleGlyphCache); |
|
302 |
||
303 |
SAFE_RELEASE(lcdTextProgram); |
|
304 |
SAFE_RELEASE(aaPgramProgram); |
|
305 |
||
306 |
SAFE_DELETE(pVCacher); |
|
307 |
SAFE_DELETE(pMaskCache); |
|
308 |
SAFE_DELETE(pResourceMgr); |
|
2 | 309 |
} |
310 |
||
311 |
D3DContext::~D3DContext() { |
|
312 |
J2dTraceLn2(J2D_TRACE_INFO, |
|
887 | 313 |
"~D3DContext: pd3dDevice=0x%x, pd3dObject =0x%x", |
314 |
pd3dDevice, pd3dObject); |
|
315 |
ReleaseContextResources(); |
|
316 |
SAFE_RELEASE(pd3dDevice); |
|
2 | 317 |
} |
318 |
||
319 |
HRESULT |
|
887 | 320 |
D3DContext::InitDevice(IDirect3DDevice9 *pd3dDevice) |
2 | 321 |
{ |
887 | 322 |
HRESULT res = S_OK; |
323 |
||
324 |
pd3dDevice->GetDeviceCaps(&devCaps); |
|
325 |
||
2 | 326 |
J2dRlsTraceLn1(J2D_TRACE_INFO, |
887 | 327 |
"D3DContext::InitDevice: device %d", adapterOrdinal); |
2 | 328 |
|
329 |
// disable some of the unneeded and costly d3d functionality |
|
887 | 330 |
pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); |
331 |
pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); |
|
332 |
pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); |
|
333 |
pd3dDevice->SetRenderState(D3DRS_CLIPPING, FALSE); |
|
334 |
pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); |
|
335 |
pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE); |
|
336 |
pd3dDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE); |
|
337 |
pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); |
|
2 | 338 |
|
887 | 339 |
// set the default texture addressing mode |
340 |
pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); |
|
341 |
pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); |
|
342 |
||
343 |
// REMIND: check supported filters with |
|
344 |
// IDirect3D9::CheckDeviceFormat with D3DUSAGE_QUERY_FILTER |
|
345 |
pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); |
|
346 |
pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); |
|
2 | 347 |
|
348 |
// these states never change |
|
887 | 349 |
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); |
350 |
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); |
|
351 |
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); |
|
352 |
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); |
|
353 |
pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); |
|
354 |
pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); |
|
355 |
pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); |
|
356 |
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); |
|
357 |
||
2 | 358 |
// init the array of latest textures |
887 | 359 |
ZeroMemory(lastTexture, sizeof(lastTexture)); |
360 |
ZeroMemory(lastTextureColorState, sizeof(lastTextureColorState)); |
|
361 |
||
362 |
opState = STATE_CHANGE; |
|
363 |
||
364 |
if (pResourceMgr == NULL) { |
|
365 |
res = D3DResourceManager::CreateInstance(this, &pResourceMgr); |
|
366 |
} else { |
|
367 |
res = pResourceMgr->Init(this); |
|
368 |
} |
|
369 |
RETURN_STATUS_IF_FAILED(res); |
|
370 |
||
371 |
if (pVCacher == NULL) { |
|
372 |
res = D3DVertexCacher::CreateInstance(this, &pVCacher); |
|
373 |
} else { |
|
374 |
res = pVCacher->Init(this); |
|
375 |
} |
|
376 |
RETURN_STATUS_IF_FAILED(res); |
|
377 |
||
378 |
if (pMaskCache == NULL) { |
|
379 |
res = D3DMaskCache::CreateInstance(this, &pMaskCache); |
|
380 |
} else{ |
|
381 |
res = pMaskCache->Init(this); |
|
382 |
} |
|
383 |
RETURN_STATUS_IF_FAILED(res); |
|
384 |
||
385 |
if (pLCDGlyphCache != NULL) { |
|
386 |
if (FAILED(res = pLCDGlyphCache->Init(this))) { |
|
387 |
// we can live without the cache |
|
388 |
SAFE_DELETE(pLCDGlyphCache); |
|
389 |
res = S_OK; |
|
390 |
} |
|
391 |
} |
|
392 |
||
393 |
if (pGrayscaleGlyphCache != NULL) { |
|
394 |
if (FAILED(res = pGrayscaleGlyphCache->Init(this))) { |
|
395 |
// we can live without the cache |
|
396 |
SAFE_DELETE(pGrayscaleGlyphCache); |
|
397 |
res = S_OK; |
|
398 |
} |
|
399 |
} |
|
2 | 400 |
|
401 |
D3DMATRIX tx; |
|
402 |
D3DUtils_SetIdentityMatrix(&tx); |
|
887 | 403 |
pd3dDevice->SetTransform(D3DTS_WORLD, &tx); |
404 |
bIsIdentityTx = TRUE; |
|
405 |
||
406 |
if (pSyncQuery == NULL) { |
|
407 |
// this is allowed to fail, do not propagate the error |
|
408 |
if (FAILED(pd3dDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pSyncQuery))) { |
|
409 |
J2dRlsTraceLn(J2D_TRACE_WARNING, |
|
410 |
"D3DContext::InitDevice: sync query not available"); |
|
411 |
pSyncQuery = NULL; |
|
412 |
} |
|
413 |
} |
|
414 |
if (pSyncRTRes == NULL) { |
|
415 |
D3DFORMAT format; |
|
416 |
if (FAILED(GetResourceManager()-> |
|
417 |
CreateRTSurface(32, 32, TRUE, TRUE, &format, &pSyncRTRes))) { |
|
418 |
J2dRlsTraceLn(J2D_TRACE_WARNING, |
|
419 |
"D3DContext::InitDevice: " |
|
420 |
"error creating sync surface"); |
|
421 |
} |
|
422 |
} |
|
2 | 423 |
|
424 |
bBeginScenePending = FALSE; |
|
425 |
||
887 | 426 |
J2dRlsTraceLn1(J2D_TRACE_INFO, |
427 |
"D3DContext::InitDefice: successfully initialized device %d", |
|
428 |
adapterOrdinal); |
|
429 |
||
430 |
return res; |
|
431 |
} |
|
432 |
||
433 |
HRESULT |
|
434 |
D3DContext::CheckAndResetDevice() |
|
435 |
{ |
|
436 |
HRESULT res = E_FAIL; |
|
437 |
||
438 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::CheckAndResetDevice"); |
|
2 | 439 |
|
887 | 440 |
if (pd3dDevice != NULL) { |
441 |
if (FAILED(res = pd3dDevice->TestCooperativeLevel())) { |
|
442 |
if (res == D3DERR_DEVICELOST) { |
|
443 |
J2dTraceLn1(J2D_TRACE_VERBOSE, " device %d is still lost", |
|
444 |
adapterOrdinal); |
|
445 |
// nothing to be done here, wait for D3DERR_DEVICENOTRESET |
|
446 |
return res; |
|
447 |
} else if (res == D3DERR_DEVICENOTRESET) { |
|
448 |
J2dTraceLn1(J2D_TRACE_VERBOSE, " device %d needs to be reset", |
|
449 |
adapterOrdinal); |
|
450 |
res = ResetContext(); |
|
451 |
} else { |
|
452 |
// some unexpected error |
|
453 |
DebugPrintD3DError(res, "D3DContext::CheckAndResetDevice: "\ |
|
454 |
"unknown error %x from TestCooperativeLevel"); |
|
455 |
} |
|
456 |
} else { |
|
457 |
J2dTraceLn1(J2D_TRACE_VERBOSE, " device %d is not lost", |
|
458 |
adapterOrdinal); |
|
2 | 459 |
} |
460 |
} else { |
|
887 | 461 |
J2dTraceLn(J2D_TRACE_VERBOSE, " null device"); |
462 |
} |
|
463 |
return res; |
|
464 |
} |
|
465 |
||
466 |
HRESULT |
|
467 |
D3DContext::ResetContext() |
|
468 |
{ |
|
469 |
HRESULT res = E_FAIL; |
|
470 |
||
471 |
J2dRlsTraceLn(J2D_TRACE_INFO, "D3DContext::ResetContext"); |
|
472 |
if (pd3dDevice != NULL) { |
|
473 |
D3DPRESENT_PARAMETERS newParams; |
|
474 |
||
475 |
newParams = curParams; |
|
476 |
||
477 |
if (newParams.Windowed) { |
|
478 |
// reset to the current display mode if we're windowed, |
|
479 |
// otherwise to the display mode we were in when the device |
|
480 |
// was lost |
|
481 |
newParams.BackBufferFormat = D3DFMT_UNKNOWN; |
|
482 |
newParams.FullScreen_RefreshRateInHz = 0; |
|
483 |
newParams.BackBufferWidth = 0; |
|
484 |
newParams.BackBufferHeight = 0; |
|
485 |
} |
|
486 |
res = ConfigureContext(&newParams); |
|
2 | 487 |
} |
488 |
return res; |
|
489 |
} |
|
490 |
||
491 |
HRESULT |
|
887 | 492 |
D3DContext::ConfigureContext(D3DPRESENT_PARAMETERS *pNewParams) |
2 | 493 |
{ |
887 | 494 |
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DContext::ConfigureContext device %d", |
495 |
adapterOrdinal); |
|
496 |
HRESULT res = S_OK; |
|
497 |
D3DFORMAT stencilFormat; |
|
498 |
HWND focusHWND = D3DPipelineManager::GetInstance()->GetCurrentFocusWindow(); |
|
499 |
D3DDEVTYPE devType = D3DPipelineManager::GetInstance()->GetDeviceType(); |
|
500 |
// this is needed so that we can find the stencil buffer format |
|
501 |
if (pNewParams->BackBufferFormat == D3DFMT_UNKNOWN) { |
|
502 |
D3DDISPLAYMODE dm; |
|
503 |
||
504 |
pd3dObject->GetAdapterDisplayMode(adapterOrdinal, &dm); |
|
505 |
pNewParams->BackBufferFormat = dm.Format; |
|
506 |
} |
|
507 |
||
508 |
stencilFormat = |
|
509 |
D3DPipelineManager::GetInstance()->GetMatchingDepthStencilFormat( |
|
510 |
adapterOrdinal, |
|
511 |
pNewParams->BackBufferFormat, pNewParams->BackBufferFormat); |
|
512 |
||
513 |
pNewParams->EnableAutoDepthStencil = TRUE; |
|
514 |
pNewParams->AutoDepthStencilFormat = stencilFormat; |
|
515 |
||
516 |
// do not set device window in the windowed mode, we use additional |
|
517 |
// swap chains for rendering, the default chain is not used. otherwise |
|
518 |
// our scratch focus window will be made visible |
|
519 |
J2dTraceLn1(J2D_TRACE_VERBOSE, " windowed=%d",pNewParams->Windowed); |
|
520 |
if (pNewParams->Windowed) { |
|
521 |
pNewParams->hDeviceWindow = (HWND)0; |
|
522 |
} |
|
523 |
||
524 |
// The focus window may change when we're entering/exiting the full-screen |
|
525 |
// mode. It may either be set to the default focus window (when there are |
|
526 |
// no more devices in fs mode), or to fs window for another device |
|
527 |
// in fs mode. See D3DPipelineManager::GetCurrentFocusWindow. |
|
528 |
if (pd3dDevice != NULL) { |
|
529 |
D3DDEVICE_CREATION_PARAMETERS cParams; |
|
530 |
pd3dDevice->GetCreationParameters(&cParams); |
|
531 |
if (cParams.hFocusWindow != focusHWND) { |
|
532 |
J2dTraceLn(J2D_TRACE_VERBOSE, |
|
533 |
" focus window changed, need to recreate the device"); |
|
534 |
||
535 |
// if fs -> windowed, first exit fs, then recreate, otherwise |
|
536 |
// the screen might be left in a different display mode |
|
537 |
if (pNewParams->Windowed && !curParams.Windowed) { |
|
538 |
J2dTraceLn(J2D_TRACE_VERBOSE, |
|
539 |
" exiting full-screen mode, reset the device"); |
|
540 |
curParams.Windowed = FALSE; |
|
541 |
ReleaseDefPoolResources(); |
|
542 |
res = pd3dDevice->Reset(&curParams); |
|
543 |
||
544 |
if (FAILED(res)) { |
|
545 |
DebugPrintD3DError(res, "D3DContext::ConfigureContext: "\ |
|
546 |
"cound not reset the device"); |
|
547 |
} |
|
548 |
} |
|
549 |
||
550 |
// note that here we should release all device resources, not only |
|
551 |
// thos in the default pool since the device is released |
|
552 |
ReleaseContextResources(); |
|
553 |
SAFE_RELEASE(pd3dDevice); |
|
554 |
} |
|
2 | 555 |
} |
556 |
||
887 | 557 |
if (pd3dDevice != NULL) { |
558 |
J2dTraceLn(J2D_TRACE_VERBOSE, " resetting the device"); |
|
559 |
||
560 |
ReleaseDefPoolResources(); |
|
561 |
||
562 |
if (pNewParams->PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE && |
|
563 |
!IsImmediateIntervalSupported()) |
|
564 |
{ |
|
565 |
pNewParams->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; |
|
566 |
} |
|
567 |
||
568 |
res = pd3dDevice->Reset(pNewParams); |
|
569 |
if (FAILED(res)) { |
|
570 |
DebugPrintD3DError(res, |
|
571 |
"D3DContext::ConfigureContext: cound not reset the device"); |
|
572 |
return res; |
|
573 |
} |
|
574 |
J2dRlsTraceLn1(J2D_TRACE_INFO, |
|
575 |
"D3DContext::ConfigureContext: successfully reset device: %d", |
|
576 |
adapterOrdinal); |
|
577 |
} else { |
|
578 |
D3DCAPS9 d3dCaps; |
|
579 |
DWORD dwBehaviorFlags; |
|
580 |
||
581 |
J2dTraceLn(J2D_TRACE_VERBOSE, " creating a new device"); |
|
582 |
||
583 |
if (FAILED(res = pd3dObject->GetDeviceCaps(adapterOrdinal, |
|
584 |
devType, &d3dCaps))) |
|
585 |
{ |
|
586 |
DebugPrintD3DError(res, |
|
587 |
"D3DContext::ConfigureContext: failed to get caps"); |
|
588 |
return res; |
|
589 |
} |
|
590 |
||
591 |
if (pNewParams->PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE && |
|
592 |
!(d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE)) |
|
593 |
{ |
|
594 |
pNewParams->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; |
|
595 |
} |
|
2 | 596 |
|
887 | 597 |
// not preserving fpu control word could cause issues (4860749) |
598 |
dwBehaviorFlags = D3DCREATE_FPU_PRESERVE; |
|
599 |
||
600 |
J2dRlsTrace(J2D_TRACE_VERBOSE, |
|
601 |
"[V] dwBehaviorFlags=D3DCREATE_FPU_PRESERVE|"); |
|
602 |
if (d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) { |
|
603 |
J2dRlsTrace(J2D_TRACE_VERBOSE, |
|
604 |
"D3DCREATE_HARDWARE_VERTEXPROCESSING"); |
|
605 |
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; |
|
606 |
} else { |
|
607 |
J2dRlsTrace(J2D_TRACE_VERBOSE, |
|
608 |
"D3DCREATE_SOFTWARE_VERTEXPROCESSING"); |
|
609 |
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; |
|
610 |
} |
|
611 |
// Handling focus changes by ourselves proved to be problematic, |
|
612 |
// so we're reverting back to D3D handling |
|
613 |
// dwBehaviorFlags |= D3DCREATE_NOWINDOWCHANGES; |
|
614 |
J2dRlsTrace(J2D_TRACE_VERBOSE,"\n"); |
|
615 |
||
616 |
if (FAILED(res = pd3dObject->CreateDevice(adapterOrdinal, devType, |
|
617 |
focusHWND, |
|
618 |
dwBehaviorFlags, |
|
619 |
pNewParams, &pd3dDevice))) |
|
620 |
{ |
|
621 |
DebugPrintD3DError(res, |
|
622 |
"D3DContext::ConfigureContext: error creating d3d device"); |
|
623 |
return res; |
|
624 |
} |
|
625 |
J2dRlsTraceLn1(J2D_TRACE_INFO, |
|
626 |
"D3DContext::ConfigureContext: successfully created device: %d", |
|
627 |
adapterOrdinal); |
|
628 |
bIsHWRasterizer = (devType == D3DDEVTYPE_HAL); |
|
629 |
} |
|
630 |
||
631 |
curParams = *pNewParams; |
|
632 |
// during the creation of the device d3d modifies this field, we reset |
|
633 |
// it back to 0 |
|
634 |
curParams.Flags = 0; |
|
635 |
||
636 |
if (FAILED(res = InitDevice(pd3dDevice))) { |
|
637 |
ReleaseContextResources(); |
|
2 | 638 |
return res; |
639 |
} |
|
640 |
||
887 | 641 |
res = InitContextCaps(); |
642 |
||
643 |
return res; |
|
644 |
} |
|
645 |
||
646 |
HRESULT |
|
647 |
D3DContext::InitContext() |
|
648 |
{ |
|
649 |
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DContext::InitContext device %d", |
|
650 |
adapterOrdinal); |
|
651 |
||
652 |
D3DPRESENT_PARAMETERS params; |
|
653 |
ZeroMemory(¶ms, sizeof(D3DPRESENT_PARAMETERS)); |
|
654 |
||
655 |
params.hDeviceWindow = 0; |
|
656 |
params.Windowed = TRUE; |
|
657 |
params.BackBufferCount = 1; |
|
658 |
params.BackBufferFormat = D3DFMT_UNKNOWN; |
|
659 |
params.SwapEffect = D3DSWAPEFFECT_DISCARD; |
|
660 |
params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; |
|
661 |
||
662 |
return ConfigureContext(¶ms); |
|
663 |
} |
|
664 |
||
665 |
HRESULT |
|
666 |
D3DContext::Sync() |
|
667 |
{ |
|
668 |
HRESULT res = S_OK; |
|
669 |
||
670 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::Sync"); |
|
671 |
||
672 |
if (pSyncQuery != NULL) { |
|
673 |
J2dTrace(J2D_TRACE_VERBOSE, " flushing the device queue.."); |
|
674 |
while (S_FALSE == |
|
675 |
(res = pSyncQuery->GetData(NULL, 0, D3DGETDATA_FLUSH))) ; |
|
676 |
J2dTrace(J2D_TRACE_VERBOSE, ".. done\n"); |
|
677 |
} |
|
678 |
if (pSyncRTRes != NULL) { |
|
679 |
D3DLOCKED_RECT lr; |
|
680 |
IDirect3DSurface9 *pSurface = pSyncRTRes->GetSurface(); |
|
681 |
if (SUCCEEDED(pSurface->LockRect(&lr, NULL, D3DLOCK_NOSYSLOCK))) { |
|
682 |
pSurface->UnlockRect(); |
|
683 |
} |
|
684 |
} |
|
685 |
return res; |
|
686 |
} |
|
687 |
||
688 |
#define POINT_FILTER_CAP (D3DPTFILTERCAPS_MAGFPOINT|D3DPTFILTERCAPS_MINFPOINT) |
|
689 |
#define LINEAR_FILTER_CAP (D3DPTFILTERCAPS_MAGFLINEAR|D3DPTFILTERCAPS_MINFLINEAR) |
|
690 |
||
691 |
BOOL |
|
692 |
D3DContext::IsStretchRectFilteringSupported(D3DTEXTUREFILTERTYPE fType) |
|
693 |
{ |
|
694 |
if (fType == D3DTEXF_POINT) { |
|
695 |
return ((devCaps.StretchRectFilterCaps & POINT_FILTER_CAP) != 0); |
|
696 |
} |
|
697 |
if (fType == D3DTEXF_LINEAR) { |
|
698 |
return ((devCaps.StretchRectFilterCaps & LINEAR_FILTER_CAP) != 0); |
|
699 |
} |
|
700 |
return FALSE; |
|
701 |
} |
|
702 |
||
703 |
BOOL |
|
704 |
D3DContext::IsTextureFilteringSupported(D3DTEXTUREFILTERTYPE fType) |
|
705 |
{ |
|
706 |
if (fType == D3DTEXF_POINT) { |
|
707 |
return ((devCaps.TextureFilterCaps & POINT_FILTER_CAP) != 0); |
|
708 |
} |
|
709 |
if (fType == D3DTEXF_LINEAR) { |
|
710 |
return ((devCaps.TextureFilterCaps & LINEAR_FILTER_CAP) != 0); |
|
711 |
} |
|
712 |
return FALSE; |
|
713 |
} |
|
714 |
||
715 |
BOOL |
|
716 |
D3DContext::IsTextureFormatSupported(D3DFORMAT format, DWORD usage) |
|
717 |
{ |
|
718 |
HRESULT hr = pd3dObject->CheckDeviceFormat(adapterOrdinal, |
|
719 |
devCaps.DeviceType, |
|
720 |
curParams.BackBufferFormat, |
|
721 |
usage, |
|
722 |
D3DRTYPE_TEXTURE, |
|
723 |
format); |
|
724 |
return SUCCEEDED( hr ); |
|
725 |
} |
|
726 |
||
727 |
BOOL |
|
728 |
D3DContext::IsDepthStencilBufferOk(D3DSURFACE_DESC *pTargetDesc) |
|
729 |
{ |
|
730 |
IDirect3DSurface9 *pStencil; |
|
731 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::IsDepthStencilBufferOk"); |
|
732 |
||
733 |
if (SUCCEEDED(pd3dDevice->GetDepthStencilSurface(&pStencil))) { |
|
734 |
D3DSURFACE_DESC descStencil; |
|
735 |
pStencil->GetDesc(&descStencil); |
|
736 |
pStencil->Release(); |
|
737 |
||
738 |
D3DDISPLAYMODE dm; |
|
739 |
return |
|
740 |
(SUCCEEDED(pd3dDevice->GetDisplayMode(0, &dm)) && |
|
741 |
pTargetDesc->Width <= descStencil.Width && |
|
742 |
pTargetDesc->Height <= descStencil.Height && |
|
743 |
SUCCEEDED(pd3dObject->CheckDepthStencilMatch( |
|
744 |
adapterOrdinal, |
|
745 |
devCaps.DeviceType, |
|
746 |
dm.Format, pTargetDesc->Format, |
|
747 |
descStencil.Format))); |
|
748 |
} |
|
749 |
J2dTraceLn(J2D_TRACE_VERBOSE, |
|
750 |
" current stencil buffer is not compatible with new Render Target"); |
|
751 |
||
752 |
return false; |
|
753 |
} |
|
754 |
||
755 |
||
756 |
||
757 |
HRESULT |
|
758 |
D3DContext::InitDepthStencilBuffer(D3DSURFACE_DESC *pTargetDesc) |
|
759 |
{ |
|
760 |
HRESULT res; |
|
761 |
IDirect3DSurface9 *pBB; |
|
762 |
D3DDISPLAYMODE dm; |
|
763 |
||
764 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::InitDepthStencilBuffer"); |
|
765 |
||
766 |
if (FAILED(res = pd3dDevice->GetDisplayMode(0, &dm))) { |
|
767 |
return res; |
|
768 |
} |
|
769 |
||
770 |
D3DFORMAT newFormat = |
|
771 |
D3DPipelineManager::GetInstance()->GetMatchingDepthStencilFormat( |
|
772 |
adapterOrdinal, dm.Format, pTargetDesc->Format); |
|
773 |
||
774 |
res = pd3dDevice->CreateDepthStencilSurface( |
|
775 |
pTargetDesc->Width, pTargetDesc->Height, |
|
776 |
newFormat, D3DMULTISAMPLE_NONE, 0, false, &pBB, 0); |
|
777 |
if (SUCCEEDED(res)) { |
|
778 |
res = pd3dDevice->SetDepthStencilSurface(pBB); |
|
779 |
pBB->Release(); |
|
2 | 780 |
} |
781 |
||
782 |
return res; |
|
783 |
} |
|
784 |
||
785 |
||
786 |
HRESULT |
|
887 | 787 |
D3DContext::SetRenderTarget(IDirect3DSurface9 *pSurface) |
2 | 788 |
{ |
789 |
static D3DMATRIX tx; |
|
887 | 790 |
HRESULT res; |
791 |
D3DSURFACE_DESC descNew; |
|
792 |
IDirect3DSurface9 *pCurrentTarget; |
|
2 | 793 |
|
887 | 794 |
J2dTraceLn1(J2D_TRACE_INFO, |
795 |
"D3DContext::SetRenderTarget: pSurface=0x%x", |
|
796 |
pSurface); |
|
2 | 797 |
|
887 | 798 |
RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); |
799 |
RETURN_STATUS_IF_NULL(pSurface, E_FAIL); |
|
2 | 800 |
|
887 | 801 |
pSurface->GetDesc(&descNew); |
2 | 802 |
|
887 | 803 |
if (SUCCEEDED(res = pd3dDevice->GetRenderTarget(0, &pCurrentTarget))) { |
804 |
if (pCurrentTarget != pSurface) { |
|
805 |
FlushVertexQueue(); |
|
806 |
if (FAILED(res = pd3dDevice->SetRenderTarget(0, pSurface))) { |
|
807 |
DebugPrintD3DError(res, "D3DContext::SetRenderTarget: "\ |
|
808 |
"error setting render target"); |
|
809 |
SAFE_RELEASE(pCurrentTarget); |
|
810 |
return res; |
|
811 |
} |
|
2 | 812 |
|
887 | 813 |
if (!IsDepthStencilBufferOk(&descNew)) { |
814 |
if (FAILED(res = InitDepthStencilBuffer(&descNew))) { |
|
815 |
SAFE_RELEASE(pCurrentTarget); |
|
816 |
return res; |
|
817 |
} |
|
818 |
} |
|
819 |
} |
|
820 |
SAFE_RELEASE(pCurrentTarget); |
|
2 | 821 |
} |
887 | 822 |
// we set the transform even if the render target didn't change; |
823 |
// this is because in some cases (fs mode) we use the default SwapChain of |
|
824 |
// the device, and its render target will be the same as the device's, and |
|
825 |
// we have to set the matrix correctly. This shouldn't be a performance |
|
826 |
// issue as render target changes are relatively rare |
|
827 |
D3DUtils_SetOrthoMatrixOffCenterLH(&tx, |
|
828 |
(float)descNew.Width, |
|
829 |
(float)descNew.Height); |
|
830 |
pd3dDevice->SetTransform(D3DTS_PROJECTION, &tx); |
|
2 | 831 |
|
887 | 832 |
J2dTraceLn1(J2D_TRACE_VERBOSE, " current render target=0x%x", pSurface); |
2 | 833 |
return res; |
834 |
} |
|
835 |
||
836 |
HRESULT |
|
887 | 837 |
D3DContext::ResetTransform() |
838 |
{ |
|
839 |
HRESULT res = S_OK; |
|
840 |
D3DMATRIX tx; |
|
841 |
||
842 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::ResetTransform"); |
|
843 |
if (pd3dDevice == NULL) { |
|
844 |
return E_FAIL; |
|
845 |
} |
|
846 |
||
847 |
// no need for state change, just flush the queue |
|
848 |
FlushVertexQueue(); |
|
849 |
||
850 |
D3DUtils_SetIdentityMatrix(&tx); |
|
851 |
if (FAILED(res = pd3dDevice->SetTransform(D3DTS_WORLD, &tx))) { |
|
852 |
DebugPrintD3DError(res, "D3DContext::SetTransform failed"); |
|
853 |
} |
|
854 |
bIsIdentityTx = TRUE; |
|
855 |
return res; |
|
856 |
} |
|
857 |
||
858 |
HRESULT |
|
859 |
D3DContext::SetTransform(jdouble m00, jdouble m10, |
|
2 | 860 |
jdouble m01, jdouble m11, |
861 |
jdouble m02, jdouble m12) |
|
862 |
{ |
|
887 | 863 |
HRESULT res = S_OK; |
864 |
D3DMATRIX tx, tx1; |
|
2 | 865 |
|
866 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::SetTransform"); |
|
887 | 867 |
if (pd3dDevice == NULL) { |
868 |
return E_FAIL; |
|
2 | 869 |
} |
870 |
||
887 | 871 |
// no need for state change, just flush the queue |
872 |
FlushVertexQueue(); |
|
873 |
||
874 |
// In order to correctly map texels to pixels we need to |
|
875 |
// adjust geometry by -0.5f in the transformed space. |
|
876 |
// In order to do that we first create a translated matrix |
|
877 |
// and then concatenate it with the world transform. |
|
878 |
// |
|
879 |
// Note that we only use non-id transform with DrawTexture, |
|
880 |
// the rest is rendered pre-transformed. |
|
881 |
// |
|
882 |
// The identity transform for textures is handled in |
|
883 |
// D3DVertexCacher::DrawTexture() because shifting by -0.5 for id |
|
884 |
// transform breaks lines rendering. |
|
885 |
||
886 |
ZeroMemory(&tx1, sizeof(D3DMATRIX)); |
|
887 |
||
888 |
tx1._11 = (float)m00; |
|
889 |
tx1._12 = (float)m10; |
|
890 |
tx1._21 = (float)m01; |
|
891 |
tx1._22 = (float)m11; |
|
892 |
tx1._41 = (float)m02; |
|
893 |
tx1._42 = (float)m12; |
|
894 |
||
895 |
tx1._33 = 1.0f; |
|
896 |
tx1._44 = 1.0f; |
|
897 |
||
898 |
D3DUtils_SetIdentityMatrix(&tx); |
|
899 |
tx._41 = -0.5f; |
|
900 |
tx._42 = -0.5f; |
|
901 |
D3DUtils_2DConcatenateM(&tx, &tx1); |
|
902 |
||
2 | 903 |
J2dTraceLn4(J2D_TRACE_VERBOSE, |
904 |
" %5f %5f %5f %5f", tx._11, tx._12, tx._13, tx._14); |
|
905 |
J2dTraceLn4(J2D_TRACE_VERBOSE, |
|
906 |
" %5f %5f %5f %5f", tx._21, tx._22, tx._23, tx._24); |
|
907 |
J2dTraceLn4(J2D_TRACE_VERBOSE, |
|
908 |
" %5f %5f %5f %5f", tx._31, tx._32, tx._33, tx._34); |
|
909 |
J2dTraceLn4(J2D_TRACE_VERBOSE, |
|
910 |
" %5f %5f %5f %5f", tx._41, tx._42, tx._43, tx._44); |
|
887 | 911 |
if (FAILED(res = pd3dDevice->SetTransform(D3DTS_WORLD, &tx))) { |
912 |
DebugPrintD3DError(res, "D3DContext::SetTransform failed"); |
|
913 |
} |
|
914 |
bIsIdentityTx = FALSE; |
|
915 |
||
916 |
return res; |
|
917 |
} |
|
918 |
||
919 |
HRESULT |
|
920 |
D3DContext::SetRectClip(int x1, int y1, int x2, int y2) |
|
921 |
{ |
|
922 |
HRESULT res = S_OK; |
|
923 |
D3DSURFACE_DESC desc; |
|
924 |
IDirect3DSurface9 *pCurrentTarget; |
|
925 |
||
926 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::SetRectClip"); |
|
927 |
J2dTraceLn4(J2D_TRACE_VERBOSE, |
|
928 |
" x1=%-4d y1=%-4d x2=%-4d y2=%-4d", |
|
929 |
x1, y1, x2, y2); |
|
930 |
||
931 |
RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); |
|
932 |
||
933 |
// no need for state change, just flush the queue |
|
934 |
FlushVertexQueue(); |
|
935 |
||
936 |
pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); |
|
937 |
||
938 |
res = pd3dDevice->GetRenderTarget(0, &pCurrentTarget); |
|
939 |
RETURN_STATUS_IF_FAILED(res); |
|
940 |
||
941 |
pCurrentTarget->GetDesc(&desc); |
|
942 |
SAFE_RELEASE(pCurrentTarget); |
|
943 |
||
944 |
if (x1 <= 0 && y1 <= 0 && |
|
945 |
(UINT)x2 >= desc.Width && (UINT)y2 >= desc.Height) |
|
946 |
{ |
|
947 |
J2dTraceLn(J2D_TRACE_VERBOSE, |
|
948 |
" disabling clip (== render target dimensions)"); |
|
949 |
return pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); |
|
2 | 950 |
} |
951 |
||
887 | 952 |
// clip to the dimensions of the target surface, otherwise |
953 |
// SetScissorRect will fail |
|
954 |
if (x1 < 0) x1 = 0; |
|
955 |
if (y1 < 0) y1 = 0; |
|
956 |
if ((UINT)x2 > desc.Width) x2 = desc.Width; |
|
957 |
if ((UINT)y2 > desc.Height) y2 = desc.Height; |
|
958 |
if (x1 > x2) x2 = x1 = 0; |
|
959 |
if (y1 > y2) y2 = y1 = 0; |
|
960 |
RECT newRect = { x1, y1, x2, y2 }; |
|
961 |
if (SUCCEEDED(res = pd3dDevice->SetScissorRect(&newRect))) { |
|
962 |
res = pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); |
|
963 |
} else { |
|
964 |
DebugPrintD3DError(res, "Error setting scissor rect"); |
|
965 |
J2dRlsTraceLn4(J2D_TRACE_ERROR, |
|
966 |
" x1=%-4d y1=%-4d x2=%-4d y2=%-4d", |
|
967 |
x1, y1, x2, y2); |
|
968 |
} |
|
969 |
||
2 | 970 |
return res; |
971 |
} |
|
972 |
||
887 | 973 |
HRESULT |
974 |
D3DContext::ResetClip() |
|
975 |
{ |
|
976 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::ResetClip"); |
|
977 |
// no need for state change, just flush the queue |
|
978 |
FlushVertexQueue(); |
|
979 |
pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); |
|
980 |
return pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); |
|
981 |
} |
|
982 |
||
983 |
ClipType |
|
984 |
D3DContext::GetClipType() |
|
985 |
{ |
|
986 |
// REMIND: this method could be optimized: we could keep the |
|
987 |
// clip state around when re/setting the clip instead of asking |
|
988 |
// every time. |
|
989 |
DWORD zEnabled = 0; |
|
990 |
DWORD stEnabled = 0; |
|
991 |
||
992 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::GetClipType"); |
|
993 |
pd3dDevice->GetRenderState(D3DRS_SCISSORTESTENABLE, &stEnabled); |
|
994 |
if (stEnabled) { |
|
995 |
return CLIP_RECT; |
|
996 |
} |
|
997 |
pd3dDevice->GetRenderState(D3DRS_ZENABLE, &zEnabled); |
|
998 |
if (zEnabled) { |
|
999 |
return CLIP_SHAPE; |
|
1000 |
} |
|
1001 |
return CLIP_NONE; |
|
1002 |
} |
|
1003 |
||
1004 |
||
2 | 1005 |
/** |
1006 |
* This method assumes that ::SetRenderTarget has already |
|
1007 |
* been called. SetRenderTarget creates and attaches a |
|
1008 |
* depth buffer to the target surface prior to setting it |
|
1009 |
* as target surface to the device. |
|
1010 |
*/ |
|
887 | 1011 |
DWORD dwAlphaSt, dwSrcBlendSt, dwDestBlendSt; |
1012 |
D3DMATRIX tx, idTx; |
|
1013 |
||
2 | 1014 |
HRESULT |
887 | 1015 |
D3DContext::BeginShapeClip() |
2 | 1016 |
{ |
887 | 1017 |
HRESULT res = S_OK; |
1018 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::BeginShapeClip"); |
|
2 | 1019 |
|
887 | 1020 |
UpdateState(STATE_CHANGE); |
2 | 1021 |
|
887 | 1022 |
pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); |
2 | 1023 |
|
887 | 1024 |
// save alpha blending state |
1025 |
pd3dDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &dwAlphaSt); |
|
1026 |
pd3dDevice->GetRenderState(D3DRS_SRCBLEND, &dwSrcBlendSt); |
|
1027 |
pd3dDevice->GetRenderState(D3DRS_DESTBLEND, &dwDestBlendSt); |
|
2 | 1028 |
|
887 | 1029 |
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); |
1030 |
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); |
|
1031 |
pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); |
|
2 | 1032 |
|
887 | 1033 |
pd3dDevice->GetTransform(D3DTS_WORLD, &tx); |
2 | 1034 |
D3DUtils_SetIdentityMatrix(&idTx); |
887 | 1035 |
// translate the clip spans by 1.0f in z direction so that the |
1036 |
// clip spans are rendered to the z buffer |
|
1037 |
idTx._43 = 1.0f; |
|
1038 |
pd3dDevice->SetTransform(D3DTS_WORLD, &idTx); |
|
2 | 1039 |
|
1040 |
// The depth buffer is first cleared with zeroes, which is the farthest |
|
1041 |
// plane from the viewer (our projection matrix is an inversed orthogonal |
|
1042 |
// transform). |
|
1043 |
// To set the clip we'll render the clip spans with Z coordinates of 1.0f |
|
1044 |
// (the closest to the viewer). Since all rendering primitives |
|
1045 |
// have their vertices' Z coordinate set to 0.0, they will effectively be |
|
1046 |
// clipped because the Z depth test for them will fail (vertex with 1.0 |
|
1047 |
// depth is closer than the one with 0.0f) |
|
887 | 1048 |
pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); |
1049 |
pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); |
|
1050 |
pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); |
|
1051 |
pd3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0L, 0.0f, 0x0L); |
|
2 | 1052 |
|
887 | 1053 |
//res = BeginScene(STATE_SHAPE_CLIPOP); |
2 | 1054 |
|
1055 |
return res; |
|
1056 |
} |
|
1057 |
||
1058 |
HRESULT |
|
887 | 1059 |
D3DContext::EndShapeClip() |
2 | 1060 |
{ |
887 | 1061 |
HRESULT res; |
2 | 1062 |
|
887 | 1063 |
// no need for state change, just flush the queue |
1064 |
res = FlushVertexQueue(); |
|
2 | 1065 |
|
887 | 1066 |
// restore alpha blending state |
1067 |
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, dwAlphaSt); |
|
1068 |
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, dwSrcBlendSt); |
|
1069 |
pd3dDevice->SetRenderState(D3DRS_DESTBLEND, dwDestBlendSt); |
|
2 | 1070 |
|
887 | 1071 |
// resore the transform |
1072 |
pd3dDevice->SetTransform(D3DTS_WORLD, &tx); |
|
2 | 1073 |
|
887 | 1074 |
// Enable the depth buffer. |
1075 |
// We disable further updates to the depth buffer: it should only |
|
1076 |
// be updated in SetClip method. |
|
1077 |
pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); |
|
1078 |
pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); |
|
2 | 1079 |
|
1080 |
return res; |
|
1081 |
} |
|
1082 |
||
887 | 1083 |
HRESULT |
1084 |
D3DContext::UploadTileToTexture(D3DResource *pTextureRes, void *pixels, |
|
1085 |
jint dstx, jint dsty, |
|
1086 |
jint srcx, jint srcy, |
|
1087 |
jint srcWidth, jint srcHeight, |
|
1088 |
jint srcStride, |
|
1089 |
TileFormat srcFormat, |
|
1090 |
jint *pPixelsTouchedL, |
|
1091 |
jint* pPixelsTouchedR) |
|
2 | 1092 |
{ |
887 | 1093 |
#ifndef PtrAddBytes |
1094 |
#define PtrAddBytes(p, b) ((void *) (((intptr_t) (p)) + (b))) |
|
58626 | 1095 |
#define PtrCoord(p, x, xinc, y, yinc) PtrAddBytes(p, \ |
1096 |
((ptrdiff_t)(y))*(yinc) + \ |
|
1097 |
((ptrdiff_t)(x))*(xinc)) |
|
887 | 1098 |
#endif // PtrAddBytes |
1099 |
||
1100 |
HRESULT res = S_OK; |
|
1101 |
IDirect3DTexture9 *pTexture = pTextureRes->GetTexture(); |
|
1102 |
D3DSURFACE_DESC *pDesc = pTextureRes->GetDesc(); |
|
1103 |
RECT r = { dstx, dsty, dstx+srcWidth, dsty+srcHeight }; |
|
1104 |
RECT *pR = &r; |
|
1105 |
D3DLOCKED_RECT lockedRect; |
|
1106 |
DWORD dwLockFlags = D3DLOCK_NOSYSLOCK; |
|
1107 |
// these are only counted for LCD glyph uploads |
|
1108 |
jint pixelsTouchedL = 0, pixelsTouchedR = 0; |
|
1109 |
||
1110 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::UploadTileToTexture"); |
|
1111 |
J2dTraceLn4(J2D_TRACE_VERBOSE, |
|
1112 |
" rect={%-4d, %-4d, %-4d, %-4d}", |
|
1113 |
r.left, r.top, r.right, r.bottom); |
|
1114 |
||
1736
f617a19a81a7
6757527: D3D: serious rendering issues on Nvidia boards with driver version 178.13 on Vista
tdv
parents:
887
diff
changeset
|
1115 |
if (pDesc->Usage == D3DUSAGE_DYNAMIC) { |
f617a19a81a7
6757527: D3D: serious rendering issues on Nvidia boards with driver version 178.13 on Vista
tdv
parents:
887
diff
changeset
|
1116 |
// it is safe to lock with discard because we don't care about the |
f617a19a81a7
6757527: D3D: serious rendering issues on Nvidia boards with driver version 178.13 on Vista
tdv
parents:
887
diff
changeset
|
1117 |
// contents of dynamic textures and dstx,dsty for this case is |
f617a19a81a7
6757527: D3D: serious rendering issues on Nvidia boards with driver version 178.13 on Vista
tdv
parents:
887
diff
changeset
|
1118 |
// always 0,0 because we are uploading into a tile texture |
887 | 1119 |
dwLockFlags |= D3DLOCK_DISCARD; |
1120 |
pR = NULL; |
|
1121 |
} |
|
1122 |
||
1123 |
if (FAILED(res = pTexture->LockRect(0, &lockedRect, pR, dwLockFlags))) { |
|
1124 |
DebugPrintD3DError(res, |
|
1125 |
"D3DContext::UploadImageToTexture: could "\ |
|
1126 |
"not lock texture"); |
|
1127 |
return res; |
|
1128 |
} |
|
2 | 1129 |
|
887 | 1130 |
if (srcFormat == TILEFMT_1BYTE_ALPHA) { |
1131 |
// either a MaskFill tile, or a grayscale glyph |
|
1132 |
if (pDesc->Format == D3DFMT_A8) { |
|
1133 |
void *pSrcPixels = PtrCoord(pixels, srcx, 1, srcy, srcStride); |
|
1134 |
void *pDstPixels = lockedRect.pBits; |
|
1135 |
do { |
|
1136 |
memcpy(pDstPixels, pSrcPixels, srcWidth); |
|
1137 |
pSrcPixels = PtrAddBytes(pSrcPixels, srcStride); |
|
1138 |
pDstPixels = PtrAddBytes(pDstPixels, lockedRect.Pitch); |
|
1139 |
} while (--srcHeight > 0); |
|
1140 |
} |
|
1141 |
else if (pDesc->Format == D3DFMT_A8R8G8B8) { |
|
1142 |
jubyte *pSrcPixels = (jubyte*) |
|
1143 |
PtrCoord(pixels, srcx, 1, srcy, srcStride); |
|
1144 |
jint *pDstPixels = (jint*)lockedRect.pBits; |
|
1145 |
for (int yy = 0; yy < srcHeight; yy++) { |
|
1146 |
for (int xx = 0; xx < srcWidth; xx++) { |
|
1147 |
// only need to set the alpha channel (the D3D texture |
|
1148 |
// state will be setup in this case to replicate the |
|
1149 |
// alpha channel as needed) |
|
1150 |
pDstPixels[xx] = pSrcPixels[xx] << 24; |
|
1151 |
} |
|
1152 |
pSrcPixels = (jubyte*)PtrAddBytes(pSrcPixels, srcStride); |
|
1153 |
pDstPixels = (jint*)PtrAddBytes(pDstPixels, lockedRect.Pitch); |
|
1154 |
} |
|
1155 |
} |
|
1156 |
} else if (srcFormat == TILEFMT_3BYTE_RGB) { |
|
1157 |
// LCD glyph with RGB order |
|
1158 |
if (pDesc->Format == D3DFMT_R8G8B8) { |
|
1159 |
jubyte *pSrcPixels = (jubyte*) |
|
1160 |
PtrCoord(pixels, srcx, 3, srcy, srcStride); |
|
1161 |
jubyte *pDstPixels = (jubyte*)lockedRect.pBits; |
|
1162 |
for (int yy = 0; yy < srcHeight; yy++) { |
|
1163 |
for (int xx = 0; xx < srcWidth*3; xx+=3) { |
|
1164 |
// alpha channel is ignored in this case |
|
1165 |
// (note that this is backwards from what one might |
|
1166 |
// expect; it appears that D3DFMT_R8G8B8 is actually |
|
1167 |
// laid out in BGR order in memory) |
|
1168 |
pDstPixels[xx+0] = pSrcPixels[xx+2]; |
|
1169 |
pDstPixels[xx+1] = pSrcPixels[xx+1]; |
|
1170 |
pDstPixels[xx+2] = pSrcPixels[xx+0]; |
|
1171 |
} |
|
1172 |
pixelsTouchedL += |
|
1173 |
(pDstPixels[0+0]|pDstPixels[0+1]|pDstPixels[0+2]) ? 1 : 0; |
|
1174 |
jint i = 3*(srcWidth-1); |
|
1175 |
pixelsTouchedR += |
|
1176 |
(pDstPixels[i+0]|pDstPixels[i+1]|pDstPixels[i+2]) ? 1 : 0; |
|
1177 |
||
1178 |
pSrcPixels = (jubyte*)PtrAddBytes(pSrcPixels, srcStride); |
|
1179 |
pDstPixels = (jubyte*)PtrAddBytes(pDstPixels, lockedRect.Pitch); |
|
1180 |
} |
|
1181 |
} |
|
1182 |
else if (pDesc->Format == D3DFMT_A8R8G8B8) { |
|
1183 |
jubyte *pSrcPixels = (jubyte*) |
|
1184 |
PtrCoord(pixels, srcx, 3, srcy, srcStride); |
|
1185 |
jint *pDstPixels = (jint*)lockedRect.pBits; |
|
1186 |
for (int yy = 0; yy < srcHeight; yy++) { |
|
1187 |
for (int dx = 0, sx = 0; dx < srcWidth; dx++, sx+=3) { |
|
1188 |
// alpha channel is ignored in this case |
|
1189 |
jubyte r = pSrcPixels[sx+0]; |
|
1190 |
jubyte g = pSrcPixels[sx+1]; |
|
1191 |
jubyte b = pSrcPixels[sx+2]; |
|
1192 |
pDstPixels[dx] = (r << 16) | (g << 8) | (b); |
|
1193 |
} |
|
1194 |
pixelsTouchedL += (pDstPixels[0] ? 1 : 0); |
|
1195 |
pixelsTouchedR += (pDstPixels[srcWidth-1] ? 1 : 0); |
|
2 | 1196 |
|
887 | 1197 |
pSrcPixels = (jubyte*)PtrAddBytes(pSrcPixels, srcStride); |
1198 |
pDstPixels = (jint*)PtrAddBytes(pDstPixels, lockedRect.Pitch); |
|
1199 |
} |
|
1200 |
} |
|
1201 |
} else if (srcFormat == TILEFMT_3BYTE_BGR) { |
|
1202 |
// LCD glyph with BGR order |
|
1203 |
if (pDesc->Format == D3DFMT_R8G8B8) { |
|
1204 |
void *pSrcPixels = PtrCoord(pixels, srcx, 3, srcy, srcStride); |
|
1205 |
void *pDstPixels = lockedRect.pBits; |
|
1206 |
jubyte *pbDst; |
|
1207 |
do { |
|
1208 |
// alpha channel is ignored in this case |
|
1209 |
// (note that this is backwards from what one might |
|
1210 |
// expect; it appears that D3DFMT_R8G8B8 is actually |
|
1211 |
// laid out in BGR order in memory) |
|
1212 |
memcpy(pDstPixels, pSrcPixels, srcWidth * 3); |
|
1213 |
||
1214 |
pbDst = (jubyte*)pDstPixels; |
|
1215 |
pixelsTouchedL +=(pbDst[0+0]|pbDst[0+1]|pbDst[0+2]) ? 1 : 0; |
|
1216 |
jint i = 3*(srcWidth-1); |
|
1217 |
pixelsTouchedR +=(pbDst[i+0]|pbDst[i+1]|pbDst[i+2]) ? 1 : 0; |
|
1218 |
||
1219 |
pSrcPixels = PtrAddBytes(pSrcPixels, srcStride); |
|
1220 |
pDstPixels = PtrAddBytes(pDstPixels, lockedRect.Pitch); |
|
1221 |
} while (--srcHeight > 0); |
|
1222 |
} |
|
1223 |
else if (pDesc->Format == D3DFMT_A8R8G8B8) { |
|
1224 |
jubyte *pSrcPixels = (jubyte*) |
|
1225 |
PtrCoord(pixels, srcx, 3, srcy, srcStride); |
|
1226 |
jint *pDstPixels = (jint*)lockedRect.pBits; |
|
1227 |
for (int yy = 0; yy < srcHeight; yy++) { |
|
1228 |
for (int dx = 0, sx = 0; dx < srcWidth; dx++, sx+=3) { |
|
1229 |
// alpha channel is ignored in this case |
|
1230 |
jubyte b = pSrcPixels[sx+0]; |
|
1231 |
jubyte g = pSrcPixels[sx+1]; |
|
1232 |
jubyte r = pSrcPixels[sx+2]; |
|
1233 |
pDstPixels[dx] = (r << 16) | (g << 8) | (b); |
|
1234 |
} |
|
1235 |
pixelsTouchedL += (pDstPixels[0] ? 1 : 0); |
|
1236 |
pixelsTouchedR += (pDstPixels[srcWidth-1] ? 1 : 0); |
|
1237 |
||
1238 |
pSrcPixels = (jubyte*)PtrAddBytes(pSrcPixels, srcStride); |
|
1239 |
pDstPixels = (jint*)PtrAddBytes(pDstPixels, lockedRect.Pitch); |
|
1240 |
} |
|
1241 |
} |
|
1242 |
} else if (srcFormat == TILEFMT_4BYTE_ARGB_PRE) { |
|
1243 |
// MaskBlit tile |
|
1244 |
if (pDesc->Format == D3DFMT_A8R8G8B8) { |
|
1245 |
void *pSrcPixels = PtrCoord(pixels, srcx, 4, srcy, srcStride); |
|
1246 |
void *pDstPixels = lockedRect.pBits; |
|
1247 |
do { |
|
1248 |
memcpy(pDstPixels, pSrcPixels, srcWidth * 4); |
|
1249 |
pSrcPixels = PtrAddBytes(pSrcPixels, srcStride); |
|
1250 |
pDstPixels = PtrAddBytes(pDstPixels, lockedRect.Pitch); |
|
1251 |
} while (--srcHeight > 0); |
|
1252 |
} |
|
2 | 1253 |
} else { |
887 | 1254 |
// should not happen, no-op just in case... |
1255 |
} |
|
1256 |
||
1257 |
if (pPixelsTouchedL) { |
|
1258 |
*pPixelsTouchedL = pixelsTouchedL; |
|
2 | 1259 |
} |
887 | 1260 |
if (pPixelsTouchedR) { |
1261 |
*pPixelsTouchedR = pixelsTouchedR; |
|
1262 |
} |
|
1263 |
||
1264 |
return pTexture->UnlockRect(0); |
|
2 | 1265 |
} |
1266 |
||
887 | 1267 |
HRESULT |
1268 |
D3DContext::InitLCDGlyphCache() |
|
1269 |
{ |
|
1270 |
if (pLCDGlyphCache == NULL) { |
|
1271 |
return D3DGlyphCache::CreateInstance(this, CACHE_LCD, &pLCDGlyphCache); |
|
1272 |
} |
|
1273 |
return S_OK; |
|
1274 |
} |
|
1275 |
||
1276 |
HRESULT |
|
1277 |
D3DContext::InitGrayscaleGlyphCache() |
|
1278 |
{ |
|
1279 |
if (pGrayscaleGlyphCache == NULL) { |
|
1280 |
return D3DGlyphCache::CreateInstance(this, CACHE_GRAY, |
|
1281 |
&pGrayscaleGlyphCache); |
|
1282 |
} |
|
1283 |
return S_OK; |
|
1284 |
} |
|
1285 |
||
1286 |
HRESULT |
|
2 | 1287 |
D3DContext::ResetComposite() |
1288 |
{ |
|
1289 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::ResetComposite"); |
|
887 | 1290 |
|
1291 |
RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); |
|
1292 |
||
1293 |
HRESULT res = UpdateState(STATE_CHANGE); |
|
1294 |
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); |
|
2 | 1295 |
extraAlpha = 1.0f; |
887 | 1296 |
return res; |
2 | 1297 |
} |
1298 |
||
887 | 1299 |
HRESULT |
2 | 1300 |
D3DContext::SetAlphaComposite(jint rule, jfloat ea, jint flags) |
1301 |
{ |
|
887 | 1302 |
HRESULT res; |
2 | 1303 |
J2dTraceLn3(J2D_TRACE_INFO, |
1304 |
"D3DContext::SetAlphaComposite: rule=%-1d ea=%f flags=%d", |
|
1305 |
rule, ea, flags); |
|
1306 |
||
887 | 1307 |
RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); |
1308 |
||
1309 |
res = UpdateState(STATE_CHANGE); |
|
2 | 1310 |
|
1311 |
// we can safely disable blending when: |
|
1312 |
// - comp is SrcNoEa or SrcOverNoEa, and |
|
1313 |
// - the source is opaque |
|
887 | 1314 |
// (turning off blending can have a large positive impact on performance) |
2 | 1315 |
if ((rule == RULE_Src || rule == RULE_SrcOver) && |
1316 |
(ea == 1.0f) && |
|
1317 |
(flags & D3DC_SRC_IS_OPAQUE)) |
|
887 | 1318 |
{ |
1319 |
J2dTraceLn1(J2D_TRACE_VERBOSE, |
|
1320 |
" disabling alpha comp rule=%-1d ea=1.0 src=opq)", rule); |
|
1321 |
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); |
|
1322 |
} else { |
|
2 | 1323 |
J2dTraceLn2(J2D_TRACE_VERBOSE, |
1324 |
" enabling alpha comp (rule=%-1d ea=%f)", rule, ea); |
|
887 | 1325 |
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); |
2 | 1326 |
|
887 | 1327 |
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, |
1328 |
StdBlendRules[rule].src); |
|
1329 |
pd3dDevice->SetRenderState(D3DRS_DESTBLEND, |
|
1330 |
StdBlendRules[rule].dst); |
|
2 | 1331 |
} |
1332 |
||
887 | 1333 |
extraAlpha = ea; |
2 | 1334 |
return res; |
1335 |
} |
|
1336 |
||
887 | 1337 |
#ifdef UPDATE_TX |
2 | 1338 |
|
887 | 1339 |
// Note: this method of adjusting pixel to texel mapping proved to be |
1340 |
// difficult to perfect. The current variation works great for id, |
|
1341 |
// scale (including all kinds of flips) transforms, but not still not |
|
1342 |
// for generic transforms. |
|
1343 |
// |
|
1344 |
// Since we currently only do DrawTexture with non-id transform we instead |
|
1345 |
// adjust the geometry (see D3DVertexCacher::DrawTexture(), SetTransform()) |
|
1346 |
// |
|
1347 |
// In order to enable this code path UpdateTextureTransforms needs to |
|
1348 |
// be called in SetTexture(), SetTransform() and ResetTranform(). |
|
1349 |
HRESULT |
|
1350 |
D3DContext::UpdateTextureTransforms(DWORD dwSamplerToUpdate) |
|
1351 |
{ |
|
1352 |
HRESULT res = S_OK; |
|
1353 |
DWORD dwSampler, dwMaxSampler; |
|
2 | 1354 |
|
887 | 1355 |
if (dwSamplerToUpdate == -1) { |
1356 |
// update all used samplers, dwMaxSampler will be set to max |
|
1357 |
dwSampler = 0; |
|
1358 |
dwSampler = MAX_USED_TEXTURE_SAMPLER; |
|
1359 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::UpdateTextureTransforms: "\ |
|
1360 |
"updating all samplers"); |
|
1361 |
} else { |
|
1362 |
// update only given sampler, dwMaxSampler will be set to it as well |
|
1363 |
dwSampler = dwSamplerToUpdate; |
|
1364 |
dwMaxSampler = dwSamplerToUpdate; |
|
1365 |
J2dTraceLn1(J2D_TRACE_INFO, "D3DContext::UpdateTextureTransforms: "\ |
|
1366 |
"updating sampler %d", dwSampler); |
|
2 | 1367 |
} |
1368 |
||
887 | 1369 |
do { |
1370 |
D3DTRANSFORMSTATETYPE state = |
|
1371 |
(D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + dwSampler); |
|
1372 |
IDirect3DTexture9 *pTexture = lastTexture[dwSampler]; |
|
1373 |
||
1374 |
if (pTexture != NULL) { |
|
1375 |
D3DMATRIX mt, tx; |
|
1376 |
D3DSURFACE_DESC texDesc; |
|
1377 |
||
1378 |
pd3dDevice->GetTransform(D3DTS_WORLD, &tx); |
|
1379 |
J2dTraceLn4(10, |
|
1380 |
" %5f %5f %5f %5f", tx._11, tx._12, tx._13, tx._14); |
|
1381 |
J2dTraceLn4(10, |
|
1382 |
" %5f %5f %5f %5f", tx._21, tx._22, tx._23, tx._24); |
|
1383 |
J2dTraceLn4(10, |
|
1384 |
" %5f %5f %5f %5f", tx._31, tx._32, tx._33, tx._34); |
|
1385 |
J2dTraceLn4(10, |
|
1386 |
" %5f %5f %5f %5f", tx._41, tx._42, tx._43, tx._44); |
|
2 | 1387 |
|
887 | 1388 |
// this formula works for scales and flips |
1389 |
if (tx._11 == 0.0f) { |
|
1390 |
tx._11 = tx._12; |
|
1391 |
} |
|
1392 |
if (tx._22 == 0.0f) { |
|
1393 |
tx._22 = tx._21; |
|
1394 |
} |
|
1395 |
||
1396 |
pTexture->GetLevelDesc(0, &texDesc); |
|
1397 |
||
1398 |
// shift by .5 texel, but take into account |
|
1399 |
// the scale factor of the device transform |
|
1400 |
||
1401 |
// REMIND: this approach is not entirely correct, |
|
1402 |
// as it only takes into account the scale of the device |
|
1403 |
// transform. |
|
1404 |
mt._31 = (1.0f / (2.0f * texDesc.Width * tx._11)); |
|
1405 |
mt._32 = (1.0f / (2.0f * texDesc.Height * tx._22)); |
|
1406 |
J2dTraceLn2(J2D_TRACE_VERBOSE, " offsets: tx=%f ty=%f", |
|
1407 |
mt._31, mt._32); |
|
1408 |
||
1409 |
pd3dDevice->SetTextureStageState(dwSampler, |
|
1410 |
D3DTSS_TEXTURETRANSFORMFLAGS, |
|
1411 |
D3DTTFF_COUNT2); |
|
1412 |
res = pd3dDevice->SetTransform(state, &mt); |
|
1413 |
} else { |
|
1414 |
res = pd3dDevice->SetTextureStageState(dwSampler, |
|
1415 |
D3DTSS_TEXTURETRANSFORMFLAGS, |
|
1416 |
D3DTTFF_DISABLE); |
|
2 | 1417 |
} |
887 | 1418 |
dwSampler++; |
1419 |
} while (dwSampler <= dwMaxSampler); |
|
2 | 1420 |
|
1421 |
return res; |
|
1422 |
} |
|
887 | 1423 |
#endif // UPDATE_TX |
2 | 1424 |
|
1425 |
/** |
|
1426 |
* We go into the pains of maintaining the list of set textures |
|
1427 |
* instead of just calling GetTexture() and comparing the old one |
|
1428 |
* with the new one because it's actually noticeably slower to call |
|
1429 |
* GetTexture() (note that we'd have to then call Release() on the |
|
1430 |
* texture since GetTexture() increases texture's ref. count). |
|
1431 |
*/ |
|
887 | 1432 |
HRESULT |
1433 |
D3DContext::SetTexture(IDirect3DTexture9 *pTexture, DWORD dwSampler) |
|
2 | 1434 |
{ |
887 | 1435 |
HRESULT res = S_OK; |
1436 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::SetTexture"); |
|
2 | 1437 |
|
887 | 1438 |
if (dwSampler < 0 || dwSampler > MAX_USED_TEXTURE_SAMPLER) { |
2 | 1439 |
J2dTraceLn1(J2D_TRACE_ERROR, |
887 | 1440 |
"D3DContext::SetTexture: incorrect sampler: %d", dwSampler); |
1441 |
return E_FAIL; |
|
2 | 1442 |
} |
887 | 1443 |
if (lastTexture[dwSampler] != pTexture) { |
1444 |
if (FAILED(res = FlushVertexQueue())) { |
|
1445 |
return res; |
|
1446 |
} |
|
1447 |
J2dTraceLn2(J2D_TRACE_VERBOSE, |
|
1448 |
" new texture=0x%x on sampler %d", pTexture, dwSampler); |
|
1449 |
res = pd3dDevice->SetTexture(dwSampler, pTexture); |
|
1450 |
if (SUCCEEDED(res)) { |
|
1451 |
lastTexture[dwSampler] = pTexture; |
|
1452 |
// REMIND: see comment at UpdateTextureTransforms |
|
1453 |
#ifdef UPDATE_TX |
|
1454 |
res = UpdateTextureTransforms(dwSampler); |
|
1455 |
#endif |
|
1456 |
} else { |
|
1457 |
lastTexture[dwSampler] = NULL; |
|
1458 |
} |
|
2 | 1459 |
} |
1460 |
return res; |
|
1461 |
} |
|
1462 |
||
887 | 1463 |
HRESULT |
1464 |
D3DContext::UpdateTextureColorState(DWORD dwState, DWORD dwSampler) |
|
2 | 1465 |
{ |
887 | 1466 |
HRESULT res = S_OK; |
2 | 1467 |
|
887 | 1468 |
if (dwState != lastTextureColorState[dwSampler]) { |
1469 |
res = pd3dDevice->SetTextureStageState(dwSampler, |
|
1470 |
D3DTSS_ALPHAARG1, dwState); |
|
1471 |
res = pd3dDevice->SetTextureStageState(dwSampler, |
|
1472 |
D3DTSS_COLORARG1, dwState); |
|
1473 |
lastTextureColorState[dwSampler] = dwState; |
|
2 | 1474 |
} |
887 | 1475 |
|
1476 |
return res; |
|
2 | 1477 |
} |
1478 |
||
887 | 1479 |
HRESULT /*NOLOCK*/ |
2 | 1480 |
D3DContext::UpdateState(jbyte newState) |
1481 |
{ |
|
887 | 1482 |
HRESULT res = S_OK; |
1483 |
||
1484 |
if (opState == newState) { |
|
1485 |
// The op is the same as last time, so we can return immediately. |
|
1486 |
return res; |
|
1487 |
} else if (opState != STATE_CHANGE) { |
|
1488 |
res = FlushVertexQueue(); |
|
1489 |
} |
|
2 | 1490 |
|
887 | 1491 |
switch (opState) { |
1492 |
case STATE_MASKOP: |
|
1493 |
pMaskCache->Disable(); |
|
1494 |
break; |
|
1495 |
case STATE_GLYPHOP: |
|
1496 |
D3DTR_DisableGlyphVertexCache(this); |
|
1497 |
break; |
|
1498 |
case STATE_TEXTUREOP: |
|
1499 |
// optimization: certain state changes (those marked STATE_CHANGE) |
|
1500 |
// are allowed while texturing is enabled. |
|
1501 |
// In this case, we can allow previousOp to remain as it is and |
|
1502 |
// then return early. |
|
1503 |
if (newState == STATE_CHANGE) { |
|
1504 |
return res; |
|
1505 |
} |
|
1506 |
// REMIND: not necessary if we are switching to MASKOP or GLYPHOP |
|
1507 |
// (or a complex paint, for that matter), but would that be a |
|
1508 |
// worthwhile optimization? |
|
1509 |
SetTexture(NULL); |
|
1510 |
break; |
|
1511 |
case STATE_AAPGRAMOP: |
|
1512 |
res = DisableAAParallelogramProgram(); |
|
1513 |
break; |
|
1514 |
default: |
|
1515 |
break; |
|
1516 |
} |
|
2 | 1517 |
|
887 | 1518 |
switch (newState) { |
1519 |
case STATE_MASKOP: |
|
1520 |
pMaskCache->Enable(); |
|
1521 |
UpdateTextureColorState(D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE); |
|
1522 |
break; |
|
1523 |
case STATE_GLYPHOP: |
|
1524 |
D3DTR_EnableGlyphVertexCache(this); |
|
1525 |
UpdateTextureColorState(D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE); |
|
1526 |
break; |
|
1527 |
case STATE_TEXTUREOP: |
|
1528 |
UpdateTextureColorState(D3DTA_TEXTURE); |
|
1529 |
break; |
|
1530 |
case STATE_AAPGRAMOP: |
|
1531 |
res = EnableAAParallelogramProgram(); |
|
1532 |
break; |
|
1533 |
default: |
|
1534 |
break; |
|
2 | 1535 |
} |
887 | 1536 |
|
1537 |
opState = newState; |
|
1538 |
||
1539 |
return res; |
|
1540 |
} |
|
1541 |
||
1542 |
HRESULT D3DContext::FlushVertexQueue() |
|
1543 |
{ |
|
1544 |
if (pVCacher != NULL) { |
|
1545 |
return pVCacher->Render(); |
|
1546 |
} |
|
1547 |
return E_FAIL; |
|
2 | 1548 |
} |
1549 |
||
1550 |
HRESULT D3DContext::BeginScene(jbyte newState) |
|
1551 |
{ |
|
887 | 1552 |
if (!pd3dDevice) { |
1553 |
return E_FAIL; |
|
2 | 1554 |
} else { |
1555 |
UpdateState(newState); |
|
1556 |
if (!bBeginScenePending) { |
|
1557 |
bBeginScenePending = TRUE; |
|
887 | 1558 |
HRESULT res = pd3dDevice->BeginScene(); |
2 | 1559 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::BeginScene"); |
1560 |
if (FAILED(res)) { |
|
1561 |
// this will cause context reinitialization |
|
887 | 1562 |
opState = STATE_CHANGE; |
2 | 1563 |
} |
1564 |
return res; |
|
1565 |
} |
|
887 | 1566 |
return S_OK; |
2 | 1567 |
} |
1568 |
} |
|
1569 |
||
887 | 1570 |
HRESULT D3DContext::EndScene() { |
1571 |
if (bBeginScenePending) { |
|
1572 |
FlushVertexQueue(); |
|
1573 |
bBeginScenePending = FALSE; |
|
1574 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::EndScene"); |
|
1575 |
return pd3dDevice->EndScene(); |
|
1576 |
} |
|
1577 |
return S_OK; |
|
1578 |
} |
|
1579 |
||
1580 |
/** |
|
1581 |
* Compiles and links the given fragment shader program. If |
|
1582 |
* successful, this function returns a handle to the newly created shader |
|
1583 |
* program; otherwise returns 0. |
|
2 | 1584 |
*/ |
887 | 1585 |
IDirect3DPixelShader9 *D3DContext::CreateFragmentProgram(DWORD **shaders, |
1586 |
ShaderList *programs, |
|
1587 |
jint flags) |
|
2 | 1588 |
{ |
887 | 1589 |
DWORD *sourceCode; |
1590 |
IDirect3DPixelShader9 *pProgram; |
|
1591 |
||
1592 |
J2dTraceLn1(J2D_TRACE_INFO, |
|
1593 |
"D3DContext::CreateFragmentProgram: flags=%d", |
|
1594 |
flags); |
|
2 | 1595 |
|
887 | 1596 |
sourceCode = shaders[flags]; |
1597 |
if (FAILED(pd3dDevice->CreatePixelShader(sourceCode, &pProgram))) { |
|
1598 |
J2dRlsTraceLn(J2D_TRACE_ERROR, |
|
1599 |
"D3DContext::CreateFragmentProgram: error creating program"); |
|
1600 |
return NULL; |
|
2 | 1601 |
} |
887 | 1602 |
|
1603 |
// add it to the cache |
|
1604 |
ShaderList_AddProgram(programs, ptr_to_jlong(pProgram), |
|
1605 |
0 /*unused*/, 0 /*unused*/, flags); |
|
1606 |
||
1607 |
return pProgram; |
|
2 | 1608 |
} |
1609 |
||
887 | 1610 |
/** |
1611 |
* Locates and enables a fragment program given a list of shader programs |
|
1612 |
* (ShaderInfos), using this context's state and flags as search |
|
1613 |
* parameters. The "flags" parameter is a bitwise-or'd value that helps |
|
1614 |
* differentiate one program for another; the interpretation of this value |
|
1615 |
* varies depending on the type of shader (BufImgOp, Paint, etc) but here |
|
1616 |
* it is only used to find another ShaderInfo with that same "flags" value. |
|
2 | 1617 |
*/ |
887 | 1618 |
HRESULT D3DContext::EnableFragmentProgram(DWORD **shaders, |
1619 |
ShaderList *programList, |
|
1620 |
jint flags) |
|
2 | 1621 |
{ |
887 | 1622 |
HRESULT res; |
1623 |
jlong programID; |
|
1624 |
IDirect3DPixelShader9 *pProgram; |
|
1625 |
||
1626 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::EnableFragmentProgram"); |
|
1627 |
||
1628 |
programID = |
|
1629 |
ShaderList_FindProgram(programList, |
|
1630 |
0 /*unused*/, 0 /*unused*/, flags); |
|
2 | 1631 |
|
887 | 1632 |
pProgram = (IDirect3DPixelShader9 *)jlong_to_ptr(programID); |
1633 |
if (pProgram == NULL) { |
|
1634 |
pProgram = CreateFragmentProgram(shaders, programList, flags); |
|
1635 |
if (pProgram == NULL) { |
|
1636 |
return E_FAIL; |
|
1637 |
} |
|
2 | 1638 |
} |
887 | 1639 |
|
1640 |
if (FAILED(res = pd3dDevice->SetPixelShader(pProgram))) { |
|
1641 |
J2dRlsTraceLn(J2D_TRACE_ERROR, |
|
1642 |
"D3DContext::EnableFragmentProgram: error setting pixel shader"); |
|
1643 |
return res; |
|
1644 |
} |
|
1645 |
||
1646 |
return S_OK; |
|
2 | 1647 |
} |
1648 |
||
887 | 1649 |
HRESULT D3DContext::EnableBasicGradientProgram(jint flags) |
2 | 1650 |
{ |
887 | 1651 |
return EnableFragmentProgram((DWORD **)gradShaders, |
1652 |
&basicGradPrograms, flags); |
|
1653 |
} |
|
2 | 1654 |
|
887 | 1655 |
HRESULT D3DContext::EnableLinearGradientProgram(jint flags) |
1656 |
{ |
|
1657 |
return EnableFragmentProgram((DWORD **)linearShaders, |
|
1658 |
&linearGradPrograms, flags); |
|
2 | 1659 |
} |
1660 |
||
887 | 1661 |
HRESULT D3DContext::EnableRadialGradientProgram(jint flags) |
1662 |
{ |
|
1663 |
return EnableFragmentProgram((DWORD **)radialShaders, |
|
1664 |
&radialGradPrograms, flags); |
|
1665 |
} |
|
1666 |
||
1667 |
HRESULT D3DContext::EnableConvolveProgram(jint flags) |
|
2 | 1668 |
{ |
887 | 1669 |
return EnableFragmentProgram((DWORD **)convolveShaders, |
1670 |
&convolvePrograms, flags); |
|
1671 |
} |
|
2 | 1672 |
|
887 | 1673 |
HRESULT D3DContext::EnableRescaleProgram(jint flags) |
1674 |
{ |
|
1675 |
return EnableFragmentProgram((DWORD **)rescaleShaders, |
|
1676 |
&rescalePrograms, flags); |
|
1677 |
} |
|
1678 |
||
1679 |
HRESULT D3DContext::EnableLookupProgram(jint flags) |
|
1680 |
{ |
|
1681 |
return EnableFragmentProgram((DWORD **)lookupShaders, |
|
1682 |
&lookupPrograms, flags); |
|
2 | 1683 |
} |
1684 |
||
887 | 1685 |
HRESULT D3DContext::EnableLCDTextProgram() |
2 | 1686 |
{ |
887 | 1687 |
HRESULT res; |
1688 |
||
1689 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::EnableLCDTextProgram"); |
|
2 | 1690 |
|
887 | 1691 |
if (lcdTextProgram == NULL) { |
1692 |
if (FAILED(res = pd3dDevice->CreatePixelShader(lcdtext0, |
|
1693 |
&lcdTextProgram))) |
|
1694 |
{ |
|
1695 |
return res; |
|
1696 |
} |
|
1697 |
} |
|
1698 |
||
1699 |
if (FAILED(res = pd3dDevice->SetPixelShader(lcdTextProgram))) { |
|
1700 |
J2dRlsTraceLn(J2D_TRACE_ERROR, |
|
1701 |
"D3DContext::EnableLCDTextProgram: error setting pixel shader"); |
|
1702 |
return res; |
|
2 | 1703 |
} |
1704 |
||
887 | 1705 |
return S_OK; |
1706 |
} |
|
1707 |
||
1708 |
HRESULT D3DContext::EnableAAParallelogramProgram() |
|
1709 |
{ |
|
1710 |
HRESULT res; |
|
1711 |
||
1712 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::EnableAAParallelogramProgram"); |
|
1713 |
||
1714 |
if (aaPgramProgram == NULL) { |
|
1715 |
if (FAILED(res = pd3dDevice->CreatePixelShader(aapgram0, |
|
1716 |
&aaPgramProgram))) { |
|
1717 |
DebugPrintD3DError(res, "D3DContext::EnableAAParallelogramProgram: " |
|
1718 |
"error creating pixel shader"); |
|
1719 |
return res; |
|
1720 |
} |
|
1721 |
} |
|
1722 |
||
1723 |
if (FAILED(res = pd3dDevice->SetPixelShader(aaPgramProgram))) { |
|
1724 |
DebugPrintD3DError(res, "D3DContext::EnableAAParallelogramProgram: " |
|
1725 |
"error setting pixel shader"); |
|
1726 |
return res; |
|
1727 |
} |
|
1728 |
||
1729 |
return S_OK; |
|
2 | 1730 |
} |
1731 |
||
887 | 1732 |
HRESULT D3DContext::DisableAAParallelogramProgram() |
2 | 1733 |
{ |
887 | 1734 |
HRESULT res; |
1735 |
||
1736 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::DisableAAParallelogramProgram"); |
|
1737 |
||
1738 |
if (aaPgramProgram != NULL) { |
|
1739 |
if (FAILED(res = pd3dDevice->SetPixelShader(NULL))) { |
|
1740 |
DebugPrintD3DError(res, |
|
1741 |
"D3DContext::DisableAAParallelogramProgram: " |
|
1742 |
"error clearing pixel shader"); |
|
1743 |
return res; |
|
1744 |
} |
|
1745 |
} |
|
2 | 1746 |
|
887 | 1747 |
return S_OK; |
1748 |
} |
|
1749 |
||
1750 |
BOOL D3DContext::IsAlphaRTSurfaceSupported() |
|
1751 |
{ |
|
1752 |
HRESULT res = pd3dObject->CheckDeviceFormat(adapterOrdinal, |
|
1753 |
devCaps.DeviceType, |
|
1754 |
curParams.BackBufferFormat, |
|
1755 |
D3DUSAGE_RENDERTARGET, |
|
1756 |
D3DRTYPE_SURFACE, |
|
1757 |
D3DFMT_A8R8G8B8); |
|
1758 |
return SUCCEEDED(res); |
|
2 | 1759 |
} |
1760 |
||
887 | 1761 |
BOOL D3DContext::IsAlphaRTTSupported() |
2 | 1762 |
{ |
887 | 1763 |
HRESULT res = pd3dObject->CheckDeviceFormat(adapterOrdinal, |
1764 |
devCaps.DeviceType, |
|
1765 |
curParams.BackBufferFormat, |
|
1766 |
D3DUSAGE_RENDERTARGET, |
|
1767 |
D3DRTYPE_TEXTURE, |
|
1768 |
D3DFMT_A8R8G8B8); |
|
1769 |
return SUCCEEDED(res); |
|
1770 |
} |
|
2 | 1771 |
|
887 | 1772 |
BOOL D3DContext::IsOpaqueRTTSupported() |
1773 |
{ |
|
1774 |
HRESULT res = pd3dObject->CheckDeviceFormat(adapterOrdinal, |
|
1775 |
devCaps.DeviceType, |
|
1776 |
curParams.BackBufferFormat, |
|
1777 |
D3DUSAGE_RENDERTARGET, |
|
1778 |
D3DRTYPE_TEXTURE, |
|
1779 |
curParams.BackBufferFormat); |
|
1780 |
return SUCCEEDED(res); |
|
2 | 1781 |
} |
1782 |
||
887 | 1783 |
HRESULT D3DContext::InitContextCaps() { |
1784 |
J2dTraceLn(J2D_TRACE_INFO, "D3DContext::InitContextCaps"); |
|
1785 |
J2dTraceLn1(J2D_TRACE_VERBOSE, " caps for adapter %d :", adapterOrdinal); |
|
1786 |
||
1787 |
if (pd3dDevice == NULL || pd3dObject == NULL) { |
|
1788 |
contextCaps = CAPS_EMPTY; |
|
1789 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_EMPTY"); |
|
1790 |
return E_FAIL; |
|
1791 |
} |
|
1792 |
||
1793 |
contextCaps = CAPS_DEVICE_OK; |
|
1794 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_DEVICE_OK"); |
|
2 | 1795 |
|
887 | 1796 |
if (IsAlphaRTSurfaceSupported()) { |
1797 |
contextCaps |= CAPS_RT_PLAIN_ALPHA; |
|
1798 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_RT_PLAIN_ALPHA"); |
|
1799 |
} |
|
1800 |
if (IsAlphaRTTSupported()) { |
|
1801 |
contextCaps |= CAPS_RT_TEXTURE_ALPHA; |
|
1802 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_RT_TEXTURE_ALPHA"); |
|
1803 |
} |
|
1804 |
if (IsOpaqueRTTSupported()) { |
|
1805 |
contextCaps |= CAPS_RT_TEXTURE_OPAQUE; |
|
1806 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_RT_TEXTURE_OPAQUE"); |
|
1807 |
} |
|
1808 |
if (IsPixelShader20Supported()) { |
|
1809 |
contextCaps |= CAPS_LCD_SHADER | CAPS_BIOP_SHADER | CAPS_PS20; |
|
1810 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, |
|
1811 |
" | CAPS_LCD_SHADER | CAPS_BIOP_SHADER | CAPS_PS20"); |
|
1812 |
// Pre-PS3.0 video boards are very slow with the AA shader, so |
|
1813 |
// we will require PS30 hw even though the shader is compiled for 2.0a |
|
1814 |
// if (IsGradientInstructionExtensionSupported()) { |
|
1815 |
// contextCaps |= CAPS_AA_SHADER; |
|
1816 |
// J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_AA_SHADER"); |
|
1817 |
// } |
|
2 | 1818 |
} |
887 | 1819 |
if (IsPixelShader30Supported()) { |
1820 |
if ((contextCaps & CAPS_AA_SHADER) == 0) { |
|
1821 |
// This flag was not already mentioned above... |
|
1822 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_AA_SHADER"); |
|
1823 |
} |
|
1824 |
contextCaps |= CAPS_PS30 | CAPS_AA_SHADER; |
|
1825 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_PS30"); |
|
1826 |
} |
|
1827 |
if (IsMultiTexturingSupported()) { |
|
1828 |
contextCaps |= CAPS_MULTITEXTURE; |
|
1829 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_MULTITEXTURE"); |
|
1830 |
} |
|
1831 |
if (!IsPow2TexturesOnly()) { |
|
1832 |
contextCaps |= CAPS_TEXNONPOW2; |
|
1833 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_TEXNONPOW2"); |
|
1834 |
} |
|
1835 |
if (!IsSquareTexturesOnly()) { |
|
1836 |
contextCaps |= CAPS_TEXNONSQUARE; |
|
1837 |
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " | CAPS_TEXNONSQUARE"); |
|
1838 |
} |
|
1839 |
return S_OK; |
|
2 | 1840 |
} |