diff options
Diffstat (limited to 'src/windows/native/sun/java2d/d3d/D3DMaskFill.cpp')
-rw-r--r-- | src/windows/native/sun/java2d/d3d/D3DMaskFill.cpp | 215 |
1 files changed, 65 insertions, 150 deletions
diff --git a/src/windows/native/sun/java2d/d3d/D3DMaskFill.cpp b/src/windows/native/sun/java2d/d3d/D3DMaskFill.cpp index e17486071..67bbfccbe 100644 --- a/src/windows/native/sun/java2d/d3d/D3DMaskFill.cpp +++ b/src/windows/native/sun/java2d/d3d/D3DMaskFill.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,187 +23,102 @@ * have any questions. */ -#include <stdlib.h> -#include <jni.h> -#include "ddrawUtils.h" -#include "GraphicsPrimitiveMgr.h" -#include "j2d_md.h" -#include "jlong.h" - #include "sun_java2d_d3d_D3DMaskFill.h" -#include "Win32SurfaceData.h" - -#include "D3DContext.h" -#include "D3DUtils.h" - +#include "D3DMaskFill.h" +#include "D3DRenderQueue.h" -extern "C" { - -inline static HRESULT doMaskFill - (JNIEnv *env, jobject self, - Win32SDOps *wsdo, D3DContext *d3dc, - jint x, jint y, jint w, jint h, - jbyteArray maskArray, - jint maskoff, jint maskscan); - - -JNIEXPORT void JNICALL -Java_sun_java2d_d3d_D3DMaskFill_MaskFill - (JNIEnv *env, jobject self, - jlong pData, jlong pCtx, - jint x, jint y, jint w, jint h, - jbyteArray maskArray, - jint maskoff, jint maskscan) +/** + * This implementation first copies the alpha tile into a texture and then + * maps that texture to the destination surface. This approach appears to + * offer the best performance despite being a two-step process. + * + * Here are some descriptions of the many variables used in this method: + * x,y - upper left corner of the tile destination + * w,h - width/height of the mask tile + * x0 - placekeeper for the original destination x location + * tw,th - width/height of the actual texture tile in pixels + * sx1,sy1 - upper left corner of the mask tile source region + * sx2,sy2 - lower left corner of the mask tile source region + * sx,sy - "current" upper left corner of the mask tile region of interest + */ +HRESULT +D3DMaskFill_MaskFill(D3DContext *d3dc, + jint x, jint y, jint w, jint h, + jint maskoff, jint maskscan, jint masklen, + unsigned char *pMask) { - Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData); - D3DContext *d3dc = (D3DContext *)jlong_to_ptr(pCtx); + HRESULT res = S_OK; J2dTraceLn(J2D_TRACE_INFO, "D3DMaskFill_MaskFill"); - J2dTraceLn4(J2D_TRACE_VERBOSE, " x=%-4d y=%-4d w=%-4d h=%-4d", - x, y, w, h); - J2dTraceLn2(J2D_TRACE_VERBOSE, " maskoff=%-4d maskscan=%-4d", - maskoff, maskscan); - - if (d3dc == NULL || wsdo == NULL) { - J2dTraceLn(J2D_TRACE_WARNING, - "D3DMaskFill_MaskFill: context is null"); - return; - } - - HRESULT res; - D3D_EXEC_PRIM_LOOP(env, res, wsdo, - doMaskFill(env, self, wsdo, d3dc, - x, y, w, h, - maskArray, maskoff, maskscan)); -} - -inline static HRESULT doMaskFill - (JNIEnv *env, jobject self, - Win32SDOps *wsdo, D3DContext *d3dc, - jint x, jint y, jint w, jint h, - jbyteArray maskArray, - jint maskoff, jint maskscan) -{ - DXSurface *maskTexture; - static J2DLVERTEX quadVerts[4] = { - { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0x0, 0.0f, 0.0f } - }; - - DDrawSurface *ddTargetSurface = d3dc->GetTargetSurface(); - if (ddTargetSurface == NULL) { - return DDERR_GENERIC; - } - ddTargetSurface->GetExclusiveAccess(); - d3dc->GetExclusiveAccess(); + RETURN_STATUS_IF_NULL(d3dc, E_FAIL); - IDirect3DDevice7 *d3dDevice = d3dc->Get3DDevice(); + J2dTraceLn4(J2D_TRACE_VERBOSE, " x=%d y=%d w=%d h=%d", x, y, w, h); + J2dTraceLn2(J2D_TRACE_VERBOSE, " maskoff=%d maskscan=%d", + maskoff, maskscan); - HRESULT res = D3D_OK; - if (maskArray) { - jubyte *pMask = - (jubyte*)env->GetPrimitiveArrayCritical(maskArray, 0); - float tx1, ty1, tx2, ty2; + { + D3DMaskCache *maskCache = d3dc->GetMaskCache(); jint tw, th, x0; jint sx1, sy1, sx2, sy2; jint sx, sy, sw, sh; - if (pMask == NULL) { - d3dc->ReleaseExclusiveAccess(); - ddTargetSurface->ReleaseExclusiveAccess(); - return DDERR_GENERIC; - } - - maskTexture = d3dc->GetMaskTexture(); - if (maskTexture == NULL || - FAILED(res = d3dc->BeginScene(STATE_MASKOP))) - { - env->ReleasePrimitiveArrayCritical(maskArray, pMask, JNI_ABORT); - d3dc->ReleaseExclusiveAccess(); - ddTargetSurface->ReleaseExclusiveAccess(); - return DDERR_GENERIC; - } - - if (FAILED(res = d3dc->SetTexture(maskTexture))) { - d3dc->EndScene(res); - env->ReleasePrimitiveArrayCritical(maskArray, pMask, JNI_ABORT); - d3dc->ReleaseExclusiveAccess(); - ddTargetSurface->ReleaseExclusiveAccess(); - return res; - } + res = d3dc->BeginScene(STATE_MASKOP); + RETURN_STATUS_IF_FAILED(res); x0 = x; - tx1 = 0.0f; - ty1 = 0.0f; - tw = D3DSD_MASK_TILE_SIZE; - th = D3DSD_MASK_TILE_SIZE; + tw = D3D_MASK_CACHE_TILE_WIDTH; + th = D3D_MASK_CACHE_TILE_HEIGHT; sx1 = maskoff % maskscan; sy1 = maskoff / maskscan; sx2 = sx1 + w; sy2 = sy1 + h; - D3DU_INIT_VERTEX_QUAD_COLOR(quadVerts, d3dc->colorPixel); - for (sy = sy1; (sy < sy2) && SUCCEEDED(res); sy += th, y += th) { + for (sy = sy1; sy < sy2; sy += th, y += th) { x = x0; sh = ((sy + th) > sy2) ? (sy2 - sy) : th; - for (sx = sx1; (sx < sx2) && SUCCEEDED(res); sx += tw, x += tw) { + for (sx = sx1; sx < sx2; sx += tw, x += tw) { sw = ((sx + tw) > sx2) ? (sx2 - sx) : tw; - if (FAILED(d3dc->UploadImageToTexture(maskTexture, - pMask, - 0, 0, sx, sy, sw, sh, - maskscan))) - { - continue; - } - - // update the lower right texture coordinates - tx2 = ((float)sw) / tw; - ty2 = ((float)sh) / th; - - D3DU_INIT_VERTEX_QUAD_XYUV(quadVerts, - (float)x, (float)y, - (float)(x+sw), (float)(y+sh), - tx1, ty1, tx2, ty2); - if (SUCCEEDED(res = ddTargetSurface->IsLost())) { - // render texture tile to the destination surface - res = d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_J2DLVERTEX, - quadVerts, 4, 0); - } - + res = maskCache->AddMaskQuad(sx, sy, x, y, sw, sh, + maskscan, pMask); } } + } + return res; +} - d3dc->EndScene(res); +JNIEXPORT void JNICALL +Java_sun_java2d_d3d_D3DMaskFill_maskFill + (JNIEnv *env, jobject self, + jint x, jint y, jint w, jint h, + jint maskoff, jint maskscan, jint masklen, + jbyteArray maskArray) +{ + D3DContext *d3dc = D3DRQ_GetCurrentContext(); + unsigned char *mask; + + J2dTraceLn(J2D_TRACE_ERROR, "D3DMaskFill_maskFill"); - env->ReleasePrimitiveArrayCritical(maskArray, pMask, JNI_ABORT); + if (maskArray != NULL) { + mask = (unsigned char *) + env->GetPrimitiveArrayCritical(maskArray, NULL); } else { - float x1 = (float)x; - float y1 = (float)y; - float x2 = x1 + (float)w; - float y2 = y1 + (float)h; - D3DU_INIT_VERTEX_QUAD_COLOR(quadVerts, d3dc->colorPixel); - D3DU_INIT_VERTEX_QUAD_XY(quadVerts, x1, y1, x2, y2); - if (SUCCEEDED(res = d3dc->BeginScene(STATE_RENDEROP))) { - if (SUCCEEDED(res = ddTargetSurface->IsLost())) { - res = d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_J2DLVERTEX, - quadVerts, 4, 0); - } - d3dc->EndScene(res); - } + mask = NULL; } - d3dc->ReleaseExclusiveAccess(); - ddTargetSurface->ReleaseExclusiveAccess(); + D3DMaskFill_MaskFill(d3dc, + x, y, w, h, + maskoff, maskscan, masklen, mask); - return res; -} + // reset current state, and ensure rendering is flushed to dest + if (d3dc != NULL) { + d3dc->FlushVertexQueue(); + } + if (mask != NULL) { + env->ReleasePrimitiveArrayCritical(maskArray, mask, JNI_ABORT); + } } |