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