1 /*
2 * Copyright (c) 2007, 2009, 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 #include <jlong.h>
28 #include "D3DSurfaceData.h"
29 #include "D3DPipelineManager.h"
30 #include "Trace.h"
31 #include "awt_Toolkit.h"
32 #include "awt_Window.h"
33 #include "awt_BitmapUtil.h"
34 #include "D3DRenderQueue.h"
35
36
37 // REMIND: move to awt_Component.h
38 extern "C" HWND AwtComponent_GetHWnd(JNIEnv *env, jlong pData);
39
40 /* This looks weird. but since some AWT headers need to be included,
41 * we end up with AWT's alloc.h macro definition of ExceptionOccurred.
42 * The reasons for that re-defintion do not apply to this code, so undef it.
43 */
44 #undef ExceptionOccurred
45
46 /**
47 * Initializes nativeWidth/Height fields of the SurfaceData object with
48 * dimensions on the native surface.
49 */
D3DSD_SetNativeDimensions(JNIEnv * env,D3DSDOps * d3dsdo)50 void D3DSD_SetNativeDimensions(JNIEnv *env, D3DSDOps *d3dsdo) {
51 jobject sdObject;
52 jint width, height;
53
54 RETURN_IF_NULL(sdObject = env->NewLocalRef(d3dsdo->sdOps.sdObject));
55
56 if (d3dsdo->pResource != NULL) {
57 width = d3dsdo->pResource->GetDesc()->Width;
58 height = d3dsdo->pResource->GetDesc()->Height;
59 } else {
60 width = d3dsdo->width;
61 height = d3dsdo->height;
62 }
63
64 JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width);
65 if (!(env->ExceptionOccurred())) {
66 JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height);
67 }
68
69 env->DeleteLocalRef(sdObject);
70 }
71
D3DSD_Flush(void * pData)72 void D3DSD_Flush(void *pData)
73 {
74 J2dTraceLn(J2D_TRACE_INFO, "D3DSD_Flush");
75 RETURN_IF_NULL(pData);
76
77 D3DSDOps *d3dsdo = (D3DSDOps*)pData;
78 if (d3dsdo->pResource != NULL) {
79 D3DContext *pCtx;
80 D3DPipelineManager *pMgr;
81
82 d3dsdo->pResource->SetSDOps(NULL);
83
84 if ((pMgr = D3DPipelineManager::GetInstance()) != NULL &&
85 SUCCEEDED(pMgr->GetD3DContext(d3dsdo->adapter, &pCtx)))
86 {
87 if (pCtx->GetResourceManager()) {
88 pCtx->GetResourceManager()->ReleaseResource(d3dsdo->pResource);
89 }
90 }
91 d3dsdo->pResource = NULL;
92 }
93 }
94
95 void
D3DSD_MarkLost(void * pData)96 D3DSD_MarkLost(void *pData)
97 {
98 D3DSDOps *d3dsdo;
99 jobject sdObject;
100 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
101
102 J2dTraceLn(J2D_TRACE_INFO, "D3DSD_MarkLost");
103
104 RETURN_IF_NULL(pData);
105
106 d3dsdo = (D3DSDOps*)pData;
107 RETURN_IF_NULL(sdObject = env->NewLocalRef(d3dsdo->sdOps.sdObject));
108
109 JNU_CallMethodByName(env, NULL, sdObject,
110 "setSurfaceLost", "(Z)V", JNI_TRUE);
111
112 env->DeleteLocalRef(sdObject);
113 }
114
115 // ------------ generic SurfaceData.h functions ----------------
116
117 void
D3DSD_Dispose(JNIEnv * env,SurfaceDataOps * ops)118 D3DSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
119 {
120 D3DSDOps *d3dsdo = (D3DSDOps *)ops;
121 RETURN_IF_NULL(d3dsdo);
122
123 JNU_CallStaticMethodByName(env, NULL, "sun/java2d/d3d/D3DSurfaceData",
124 "dispose", "(J)V",
125 ptr_to_jlong(ops));
126 }
127
128 /**
129 * This is the implementation of the general surface LockFunc defined in
130 * SurfaceData.h.
131 */
132 jint
D3DSD_Lock(JNIEnv * env,SurfaceDataOps * ops,SurfaceDataRasInfo * pRasInfo,jint lockflags)133 D3DSD_Lock(JNIEnv *env,
134 SurfaceDataOps *ops,
135 SurfaceDataRasInfo *pRasInfo,
136 jint lockflags)
137 {
138 JNU_ThrowInternalError(env, "D3DSD_Lock not implemented!");
139 return SD_FAILURE;
140 }
141
142 /**
143 * This is the implementation of the general GetRasInfoFunc defined in
144 * SurfaceData.h.
145 */
146 void
D3DSD_GetRasInfo(JNIEnv * env,SurfaceDataOps * ops,SurfaceDataRasInfo * pRasInfo)147 D3DSD_GetRasInfo(JNIEnv *env,
148 SurfaceDataOps *ops,
149 SurfaceDataRasInfo *pRasInfo)
150 {
151 JNU_ThrowInternalError(env, "D3DSD_GetRasInfo not implemented!");
152 }
153
154 /**
155 * This is the implementation of the general surface UnlockFunc defined in
156 * SurfaceData.h.
157 */
158 void
D3DSD_Unlock(JNIEnv * env,SurfaceDataOps * ops,SurfaceDataRasInfo * pRasInfo)159 D3DSD_Unlock(JNIEnv *env,
160 SurfaceDataOps *ops,
161 SurfaceDataRasInfo *pRasInfo)
162 {
163 JNU_ThrowInternalError(env, "D3DSD_Unlock not implemented!");
164 }
165
166 // ------------ D3DSurfaceData's JNI methods ----------------
167
168
169 extern "C" {
170
171 /*
172 * Class: sun_java2d_d3d_D3DSurfaceData
173 * Method: initOps
174 * Signature: (III)V
175 */
176 JNIEXPORT void
Java_sun_java2d_d3d_D3DSurfaceData_initOps(JNIEnv * env,jobject d3dsd,jint gdiScreen,jint width,jint height)177 JNICALL Java_sun_java2d_d3d_D3DSurfaceData_initOps
178 (JNIEnv *env, jobject d3dsd, jint gdiScreen, jint width, jint height)
179 {
180 D3DPipelineManager *pMgr;
181 D3DSDOps *d3dsdo = (D3DSDOps *)SurfaceData_InitOps(env, d3dsd,
182 sizeof(D3DSDOps));
183
184 J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initOps");
185
186 if (d3dsdo == NULL) {
187 JNU_ThrowOutOfMemoryError(env, "creating native d3d ops");
188 return;
189 }
190
191 d3dsdo->sdOps.Lock = D3DSD_Lock;
192 d3dsdo->sdOps.GetRasInfo = D3DSD_GetRasInfo;
193 d3dsdo->sdOps.Unlock = D3DSD_Unlock;
194 d3dsdo->sdOps.Dispose = D3DSD_Dispose;
195
196 d3dsdo->xoff = 0;
197 d3dsdo->yoff = 0;
198 d3dsdo->width = width;
199 d3dsdo->height = height;
200
201 d3dsdo->pResource = NULL;
202
203 d3dsdo->adapter =
204 (pMgr = D3DPipelineManager::GetInstance()) == NULL ?
205 D3DADAPTER_DEFAULT :
206 pMgr->GetAdapterOrdinalForScreen(gdiScreen);
207 }
208
209
210 /*
211 * Class: sun_java2d_d3d_D3DSurfaceData
212 * Method: initTexture
213 * Signature: (JZZ)Z
214 */
215 JNIEXPORT jboolean
Java_sun_java2d_d3d_D3DSurfaceData_initTexture(JNIEnv * env,jobject d3dsd,jlong pData,jboolean isRTT,jboolean isOpaque)216 JNICALL Java_sun_java2d_d3d_D3DSurfaceData_initTexture
217 (JNIEnv *env, jobject d3dsd,
218 jlong pData, jboolean isRTT, jboolean isOpaque)
219 {
220 HRESULT res;
221 D3DSDOps *d3dsdo;
222 D3DContext *pCtx;
223 D3DPipelineManager *pMgr;
224 D3DFORMAT format;
225
226 J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initTexture");
227
228 RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), JNI_FALSE);
229 RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
230
231 if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
232 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
233 return JNI_FALSE;
234 }
235 RETURN_STATUS_IF_NULL(pCtx->GetResourceManager(), JNI_FALSE);
236
237 pCtx->GetResourceManager()->ReleaseResource(d3dsdo->pResource);
238 d3dsdo->pResource = NULL;
239
240 if (isRTT && isOpaque) {
241 format = pCtx->GetPresentationParams()->BackBufferFormat;
242 } else {
243 format = D3DFMT_UNKNOWN;
244 }
245
246 res = pCtx->GetResourceManager()->
247 CreateTexture(d3dsdo->width, d3dsdo->height,
248 isRTT, isOpaque,
249 &format, 0/*usage*/, &d3dsdo->pResource);
250 if (SUCCEEDED(res)) {
251 J2dTraceLn1(J2D_TRACE_VERBOSE,
252 " created texture pResource=%x", d3dsdo->pResource);
253 d3dsdo->pResource->SetSDOps(d3dsdo);
254 } else {
255 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
256 }
257 D3DSD_SetNativeDimensions(env, d3dsdo);
258
259 return SUCCEEDED(res);
260 }
261
262 /*
263 * Class: sun_java2d_d3d_D3DSurfaceData
264 * Method: initPlain
265 * Signature: (JZ)Z
266 */
267 JNIEXPORT jboolean JNICALL
Java_sun_java2d_d3d_D3DSurfaceData_initRTSurface(JNIEnv * env,jobject d3dsd,jlong pData,jboolean isOpaque)268 Java_sun_java2d_d3d_D3DSurfaceData_initRTSurface
269 (JNIEnv *env, jobject d3dsd, jlong pData, jboolean isOpaque)
270 {
271 HRESULT res;
272 D3DSDOps *d3dsdo;
273 D3DContext *pCtx;
274 D3DPipelineManager *pMgr;
275 D3DFORMAT format = D3DFMT_UNKNOWN;
276
277 J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initRTSurface");
278
279 RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), JNI_FALSE);
280 RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
281
282 if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
283 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
284 return JNI_FALSE;
285 }
286 RETURN_STATUS_IF_NULL(pCtx->GetResourceManager(), JNI_FALSE);
287
288 pCtx->GetResourceManager()->ReleaseResource(d3dsdo->pResource);
289 d3dsdo->pResource = NULL;
290
291 res = pCtx->GetResourceManager()->
292 CreateRTSurface(d3dsdo->width, d3dsdo->height,
293 isOpaque, FALSE /*lockable*/,
294 &format, &d3dsdo->pResource);
295 if (SUCCEEDED(res)) {
296 J2dTraceLn1(J2D_TRACE_VERBOSE, " created RT surface pResource=0x%x",
297 d3dsdo->pResource);
298 d3dsdo->pResource->SetSDOps(d3dsdo);
299 } else {
300 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
301 }
302 D3DSD_SetNativeDimensions(env, d3dsdo);
303
304 return SUCCEEDED(res);
305 }
306
307 /*
308 * Class: sun_java2d_d3d_D3DSurfaceData
309 * Method: initFlipBackbuffer
310 * Signature: (JJIZ)Z
311 */
312 JNIEXPORT jboolean
Java_sun_java2d_d3d_D3DSurfaceData_initFlipBackbuffer(JNIEnv * env,jobject d3dsd,jlong pData,jlong pPeerData,jint numBuffers,jint swapEffect,jint vSyncType)313 JNICALL Java_sun_java2d_d3d_D3DSurfaceData_initFlipBackbuffer
314 (JNIEnv *env, jobject d3dsd, jlong pData, jlong pPeerData,
315 jint numBuffers, jint swapEffect,
316 jint vSyncType)
317 {
318 HRESULT res;
319 D3DSDOps *d3dsdo;
320 D3DContext *pCtx;
321 D3DPipelineManager *pMgr;
322 HWND hWnd;
323 UINT presentationInterval;
324 AwtComponent *pPeer;
325 RECT r = { 0, 0, 0, 0 };
326
327 J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initFlipBackbuffer");
328
329 RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), JNI_FALSE);
330 RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
331 RETURN_STATUS_IF_NULL(pPeer = (AwtComponent *)jlong_to_ptr(pPeerData),
332 JNI_FALSE);
333
334 hWnd = pPeer->GetHWnd();
335 if (!IsWindow(hWnd)) {
336 J2dTraceLn(J2D_TRACE_WARNING,
337 "D3DSurfaceData_initFlipBackbuffer: disposed component");
338 return JNI_FALSE;
339 }
340
341 pPeer->GetInsets(&r);
342 d3dsdo->xoff = -r.left;
343 d3dsdo->yoff = -r.top;
344
345 if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
346 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
347 return JNI_FALSE;
348 }
349 RETURN_STATUS_IF_NULL(pCtx->GetResourceManager(), JNI_FALSE);
350
351 pCtx->GetResourceManager()->ReleaseResource(d3dsdo->pResource);
352 d3dsdo->pResource = NULL;
353
354 d3dsdo->swapEffect = (D3DSWAPEFFECT)swapEffect;
355
356 // in full-screen mode we should v-sync
357 if (pCtx->GetPresentationParams()->Windowed) {
358 if (vSyncType == VSYNC_ON) {
359 presentationInterval = D3DPRESENT_INTERVAL_ONE;
360 J2dTraceLn(J2D_TRACE_VERBOSE,
361 " windowed, forced interval: ONE");
362 } else {
363 presentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
364 J2dTraceLn(J2D_TRACE_VERBOSE,
365 " windowed, default interval: IMMEDIATE");
366 }
367
368 // REMIND: this is a workaround for the current issue
369 // we have with non-copy flip chains: since we can not specify
370 // the dest rectangle for Present for these modes, the result of
371 // Present(NULL, NULL) is scaled to the client area.
372 if (d3dsdo->xoff != 0 || d3dsdo->yoff != 0) {
373 d3dsdo->swapEffect = D3DSWAPEFFECT_COPY;
374 }
375 } else {
376 if (vSyncType == VSYNC_OFF) {
377 presentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
378 J2dTraceLn(J2D_TRACE_VERBOSE,
379 " full-screen, forced interval: IMMEDIATE");
380 } else {
381 presentationInterval = D3DPRESENT_INTERVAL_ONE;
382 J2dTraceLn(J2D_TRACE_VERBOSE,
383 " full-screen, default interval: ONE");
384 }
385 }
386
387 res = pCtx->GetResourceManager()->
388 CreateSwapChain(hWnd, numBuffers,
389 d3dsdo->width, d3dsdo->height,
390 d3dsdo->swapEffect, presentationInterval,
391 &d3dsdo->pResource);
392 if (SUCCEEDED(res)) {
393 J2dTraceLn1(J2D_TRACE_VERBOSE, " created swap chain pResource=0x%x",
394 d3dsdo->pResource);
395 d3dsdo->pResource->SetSDOps(d3dsdo);
396 } else {
397 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
398 }
399 D3DSD_SetNativeDimensions(env, d3dsdo);
400
401 return SUCCEEDED(res);
402 }
403
404 /*
405 * Class: sun_java2d_d3d_D3DSurfaceData
406 * Method: dbGetPixelNative
407 * Signature: (JII)I
408 */
Java_sun_java2d_d3d_D3DSurfaceData_dbGetPixelNative(JNIEnv * env,jclass clazz,jlong pData,jint x,jint y)409 JNIEXPORT jint JNICALL Java_sun_java2d_d3d_D3DSurfaceData_dbGetPixelNative
410 (JNIEnv *env, jclass clazz, jlong pData, jint x, jint y)
411 {
412 HRESULT res;
413 D3DSDOps *d3dsdo;
414 D3DContext *pCtx;
415 D3DPipelineManager *pMgr;
416 D3DResource *pLockableRes;
417 jint pixel = 0;
418
419 J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_dbGetPixelNative");
420
421 RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), pixel);
422 RETURN_STATUS_IF_NULL(d3dsdo->pResource, pixel);
423 RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), pixel);
424
425 if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
426 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
427 return pixel;
428 }
429 RETURN_STATUS_IF_NULL(pCtx->GetResourceManager(), 0);
430
431 IDirect3DDevice9 *pd3dDevice = pCtx->Get3DDevice();
432 IDirect3DSurface9 *pSrc = d3dsdo->pResource->GetSurface();
433 D3DFORMAT srcFmt = d3dsdo->pResource->GetDesc()->Format;
434
435 pCtx->UpdateState(STATE_OTHEROP);
436
437 res = pCtx->GetResourceManager()->
438 GetLockableRTSurface(1, 1, srcFmt, &pLockableRes);
439 if (SUCCEEDED(res)) {
440 IDirect3DSurface9 *pTmpSurface;
441 RECT srcRect = { x, y, x+1, y+1};
442 RECT dstRect = { 0l, 0l, 1, 1 };
443
444 pTmpSurface = pLockableRes->GetSurface();
445 res = pd3dDevice->StretchRect(pSrc, &srcRect, pTmpSurface, &dstRect,
446 D3DTEXF_NONE);
447 if (SUCCEEDED(res)) {
448 D3DLOCKED_RECT lRect;
449
450 res = pTmpSurface->LockRect(&lRect, &dstRect, D3DLOCK_NOSYSLOCK);
451 if (SUCCEEDED(res)) {
452 if (srcFmt == D3DFMT_X8R8G8B8) {
453 pixel = *(jint*)lRect.pBits;
454 } else {
455 pixel = *(unsigned short*)lRect.pBits;
456 }
457 pTmpSurface->UnlockRect();
458 }
459 }
460 }
461 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
462
463 return pixel;
464 }
465
466 /*
467 * Class: sun_java2d_d3d_D3DSurfaceData
468 * Method: dbSetPixelNative
469 * Signature: (JIII)V
470 */
Java_sun_java2d_d3d_D3DSurfaceData_dbSetPixelNative(JNIEnv * env,jclass clazz,jlong pData,jint x,jint y,jint pixel)471 JNIEXPORT void JNICALL Java_sun_java2d_d3d_D3DSurfaceData_dbSetPixelNative
472 (JNIEnv *env, jclass clazz, jlong pData, jint x, jint y, jint pixel)
473 {
474 HRESULT res;
475 D3DSDOps *d3dsdo;
476 D3DResource *pLockableRes;
477 D3DContext *pCtx;
478 D3DPipelineManager *pMgr;
479
480 J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_dbSetPixelNative");
481
482 RETURN_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData));
483 RETURN_IF_NULL(d3dsdo->pResource);
484 RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance());
485
486 if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
487 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
488 return;
489 }
490 RETURN_IF_NULL(pCtx->GetResourceManager());
491
492 IDirect3DDevice9 *pd3dDevice = pCtx->Get3DDevice();
493 IDirect3DSurface9 *pSrc = d3dsdo->pResource->GetSurface();
494 D3DFORMAT srcFmt = d3dsdo->pResource->GetDesc()->Format;
495
496 pCtx->UpdateState(STATE_OTHEROP);
497
498 res = pCtx->GetResourceManager()->
499 GetLockableRTSurface(1, 1, srcFmt, &pLockableRes);
500 if (SUCCEEDED(res)) {
501 IDirect3DSurface9 *pTmpSurface;
502 D3DLOCKED_RECT lRect;
503 RECT srcRect = { 0l, 0l, 1, 1 };
504 RECT dstRect = { x, y, x+1, y+1};
505
506 pTmpSurface = pLockableRes->GetSurface();
507 res = pTmpSurface->LockRect(&lRect, &srcRect, D3DLOCK_NOSYSLOCK);
508 if (SUCCEEDED(res)) {
509 if (srcFmt == D3DFMT_X8R8G8B8) {
510 *(jint*)lRect.pBits = pixel;
511 } else {
512 *(unsigned short*)lRect.pBits = (unsigned short)pixel;
513 }
514 pTmpSurface->UnlockRect();
515
516 res = pd3dDevice->StretchRect(pTmpSurface, &srcRect, pSrc, &dstRect,
517 D3DTEXF_NONE);
518 }
519 }
520 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
521 }
522
523 /*
524 * Class: sun_java2d_d3d_D3DSurfaceData
525 * Method: getNativeResourceNative
526 * Signature: (JI)J
527 */
528 JNIEXPORT jlong JNICALL
Java_sun_java2d_d3d_D3DSurfaceData_getNativeResourceNative(JNIEnv * env,jclass d3sdc,jlong pData,jint resType)529 Java_sun_java2d_d3d_D3DSurfaceData_getNativeResourceNative
530 (JNIEnv *env, jclass d3sdc, jlong pData, jint resType)
531 {
532 D3DSDOps *d3dsdo;
533
534 J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_getNativeResourceNative")
535
536 RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), 0L);
537
538 if (resType == D3D_DEVICE_RESOURCE) {
539 HRESULT res;
540 D3DPipelineManager *pMgr;
541 D3DContext *pCtx;
542
543 RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), 0L);
544 if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
545 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
546 return 0L;
547 }
548 return ptr_to_jlong(pCtx->Get3DDevice());
549 }
550
551 RETURN_STATUS_IF_NULL(d3dsdo->pResource, 0L);
552
553 if (resType == RT_PLAIN || resType == RT_TEXTURE) {
554 return ptr_to_jlong(d3dsdo->pResource->GetSurface());
555 }
556 if (resType == TEXTURE) {
557 return ptr_to_jlong(d3dsdo->pResource->GetTexture());
558 }
559 if (resType == FLIP_BACKBUFFER) {
560 return ptr_to_jlong(d3dsdo->pResource->GetSwapChain());
561 }
562
563 return 0L;
564 }
565
566 /*
567 * Class: sun_java2d_d3d_D3DSurfaceData
568 * Method: updateWindowAccelImpl
569 * Signature: (JJII)Z
570 */
571 JNIEXPORT jboolean
Java_sun_java2d_d3d_D3DSurfaceData_updateWindowAccelImpl(JNIEnv * env,jclass clazz,jlong pd3dsd,jlong pData,jint w,jint h)572 JNICALL Java_sun_java2d_d3d_D3DSurfaceData_updateWindowAccelImpl
573 (JNIEnv *env, jclass clazz, jlong pd3dsd, jlong pData, jint w, jint h)
574 {
575 HRESULT res;
576 AwtWindow *window;
577 HBITMAP hBitmap = NULL;
578 D3DSDOps *d3dsdo;
579 D3DResource *pSrcRes;
580 D3DContext *pCtx;
581 D3DPipelineManager *pMgr;
582 D3DResource *pLockableRes = NULL;
583 IDirect3DSurface9 *pTmpSurface = NULL;
584 IDirect3DDevice9 *pd3dDevice = NULL;
585 D3DLOCKED_RECT lockedRect;
586
587 J2dTraceLn(J2D_TRACE_ERROR, "D3DSurfaceData_updateWindowAccelImpl");
588
589 if (w <= 0 || h <= 0) {
590 return JNI_TRUE;
591 }
592
593 RETURN_STATUS_IF_NULL(window = (AwtWindow *)jlong_to_ptr(pData), JNI_FALSE);
594 RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pd3dsd), JNI_FALSE);
595 RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
596 RETURN_STATUS_IF_NULL(pSrcRes = d3dsdo->pResource, JNI_FALSE);
597
598 if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
599 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
600 return JNI_FALSE;
601 }
602
603 RETURN_STATUS_IF_NULL(pd3dDevice = pCtx->Get3DDevice(), JNI_FALSE);
604 pCtx->UpdateState(STATE_OTHEROP);
605
606 res = pCtx->GetResourceManager()->
607 GetBlitOSPSurface(pSrcRes->GetDesc()->Width,
608 pSrcRes->GetDesc()->Height,
609 pSrcRes->GetDesc()->Format,
610 &pLockableRes);
611 if (FAILED(res)) {
612 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
613 return JNI_FALSE;
614 }
615 pTmpSurface = pLockableRes->GetSurface();
616
617 res = pd3dDevice->GetRenderTargetData(pSrcRes->GetSurface(), pTmpSurface);
618 if (FAILED(res)) {
619 D3DRQ_MarkLostIfNeeded(res, d3dsdo);
620 return JNI_FALSE;
621 }
622
623 res = pTmpSurface->LockRect(&lockedRect, NULL, D3DLOCK_NOSYSLOCK);
624 if (SUCCEEDED(res)) {
625 hBitmap =
626 BitmapUtil::CreateBitmapFromARGBPre(w, h,
627 lockedRect.Pitch,
628 (int*)lockedRect.pBits);
629 pTmpSurface->UnlockRect();
630 }
631 RETURN_STATUS_IF_NULL(hBitmap, JNI_FALSE);
632
633 window->UpdateWindow(env, NULL, w, h, hBitmap);
634
635 // hBitmap is released in UpdateWindow
636
637 return JNI_TRUE;
638 }
639 }
640