Exemplo n.º 1
0
void NAME_CONVERT_BLIT(Index8Gray, Index8Gray)
    (void *srcBase, void *dstBase,
     juint width, juint height,
     SurfaceDataRasInfo *pSrcInfo,
     SurfaceDataRasInfo *pDstInfo,
     NativePrimitive *pPrim,
     CompositeInfo *pCompInfo)
{
    DeclareIndex8GrayLoadVars(SrcRead)
    DeclareIndex8GrayLoadVars(DstRead)
    jint srcScan = pSrcInfo->scanStride;
    jint dstScan = pDstInfo->scanStride;

    InitIndex8GrayLoadVars(SrcRead, pSrcInfo);
    InitIndex8GrayLoadVars(DstRead, pDstInfo);

    if (checkSameLut(SrcReadLut, DstReadLut, pSrcInfo, pDstInfo)) {
        do {
            memcpy(dstBase, srcBase, width);
            srcBase = PtrAddBytes(srcBase, srcScan);
            dstBase = PtrAddBytes(dstBase, dstScan);
        } while (--height > 0);
    } else {
        DeclareIndex8GrayStoreVars(DstWrite);
        InitIndex8GrayStoreVarsY(DstWrite, pDstInfo);

        BlitLoopWidthHeight(Index8Gray, pSrc, srcBase, pSrcInfo,
                            Index8Gray, pDst, dstBase, pDstInfo, DstWrite,
                            width, height,
                            ConvertVia1ByteGray
                                (pSrc, Index8Gray, SrcRead,
                                 pDst, Index8Gray, DstWrite, 0, 0));
    }
}
/*
 * This function initializes the global collection of SurfaceType
 * or CompositeType structures by retrieving the corresponding Java
 * object stored as a static field on the Java Class.
 *
 * See SurfaceTypes.* below.
 * See CompositeeTypes.* below.
 */
static jboolean InitSimpleTypes
    (JNIEnv *env, jclass SimpleClass, char *SimpleSig,
     SurfCompHdr *pStart, SurfCompHdr *pEnd, jsize size)
{
    jboolean ok = JNI_TRUE;
    SurfCompHdr *pHdr;
    jfieldID field;
    jobject obj;

    for (pHdr = pStart; pHdr < pEnd; pHdr = PtrAddBytes(pHdr, size)) {
        field = (*env)->GetStaticFieldID(env,
                                         SimpleClass,
                                         pHdr->Name,
                                         SimpleSig);
        if (field == NULL) {
            ok = JNI_FALSE;
            break;
        }
        obj = (*env)->GetStaticObjectField(env, SimpleClass, field);
        if (obj == NULL) {
            ok = JNI_FALSE;
            break;
        }
        pHdr->Object = (*env)->NewGlobalRef(env, obj);
        (*env)->DeleteLocalRef(env, obj);
        if (pHdr->Object == NULL) {
            ok = JNI_FALSE;
            break;
        }
    }

    if (!ok) {
        for (pHdr = pStart; pHdr < pEnd; pHdr = PtrAddBytes(pHdr, size)) {
            if (pHdr->Object != NULL) {
                (*env)->DeleteGlobalRef(env, pHdr->Object);
                pHdr->Object = NULL;
            }
        }
    }

    return ok;
}
/**
 * This implementation of MaskBlit first combines the source system memory
 * tile with the corresponding alpha mask and stores the resulting
 * IntArgbPre pixels directly into the RenderBuffer.  Those pixels are
 * then eventually pulled off the RenderBuffer and copied to the destination
 * surface in OGL/D3DMaskBlit.
 *
 * Note that currently there are only inner loops defined for IntArgb,
 * IntArgbPre, IntRgb, and IntBgr, as those are the most commonly used
 * formats for this operation.
 */
JNIEXPORT jint JNICALL
Java_sun_java2d_pipe_BufferedMaskBlit_enqueueTile
    (JNIEnv *env, jobject mb,
     jlong buf, jint bpos,
     jobject srcData, jlong pSrcOps, jint srcType,
     jbyteArray maskArray, jint masklen, jint maskoff, jint maskscan,
     jint srcx, jint srcy, jint dstx, jint dsty,
     jint width, jint height)
{
    SurfaceDataOps *srcOps = (SurfaceDataOps *)jlong_to_ptr(pSrcOps);
    SurfaceDataRasInfo srcInfo;
    unsigned char *pMask;
    unsigned char *bbuf;
    jint *pBuf;

    J2dTraceLn1(J2D_TRACE_INFO,
                "BufferedMaskBlit_enqueueTile: bpos=%d",
                bpos);

    if (srcOps == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "BufferedMaskBlit_enqueueTile: srcOps is null");
        return bpos;
    }

    bbuf = (unsigned char *)jlong_to_ptr(buf);
    if (bbuf == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "BufferedMaskBlit_enqueueTile: cannot get direct buffer address");
        return bpos;
    }
    pBuf = (jint *)(bbuf + bpos);

    if (JNU_IsNull(env, maskArray)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "BufferedMaskBlit_enqueueTile: mask array is null");
        return bpos;
    }

    if (masklen > MAX_MASK_LENGTH) {
        // REMIND: this approach is seriously flawed if the mask
        //         length is ever greater than MAX_MASK_LENGTH (won't fit
        //         into the cached mask tile); so far this hasn't
        //         been a problem though...
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "BufferedMaskBlit_enqueueTile: mask array too large");
        return bpos;
    }

    pMask = (*env)->GetPrimitiveArrayCritical(env, maskArray, 0);
    if (pMask == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "BufferedMaskBlit_enqueueTile: cannot lock mask array");
        return bpos;
    }

    srcInfo.bounds.x1 = srcx;
    srcInfo.bounds.y1 = srcy;
    srcInfo.bounds.x2 = srcx + width;
    srcInfo.bounds.y2 = srcy + height;

    if (srcOps->Lock(env, srcOps, &srcInfo, SD_LOCK_READ) != SD_SUCCESS) {
        J2dRlsTraceLn(J2D_TRACE_WARNING,
                      "BufferedMaskBlit_enqueueTile: could not acquire lock");
        (*env)->ReleasePrimitiveArrayCritical(env, maskArray,
                                              pMask, JNI_ABORT);
        return bpos;
    }

    if (srcInfo.bounds.x2 > srcInfo.bounds.x1 &&
        srcInfo.bounds.y2 > srcInfo.bounds.y1)
    {
        srcOps->GetRasInfo(env, srcOps, &srcInfo);
        if (srcInfo.rasBase) {
            jint h;
            jint srcScanStride = srcInfo.scanStride;
            jint srcPixelStride = srcInfo.pixelStride;
            jint *pSrc = (jint *)
                PtrCoord(srcInfo.rasBase,
                         srcInfo.bounds.x1, srcInfo.pixelStride,
                         srcInfo.bounds.y1, srcInfo.scanStride);

            width = srcInfo.bounds.x2 - srcInfo.bounds.x1;
            height = srcInfo.bounds.y2 - srcInfo.bounds.y1;
            maskoff += ((srcInfo.bounds.y1 - srcy) * maskscan +
                        (srcInfo.bounds.x1 - srcx));
            maskscan -= width;
            pMask += maskoff;
            srcScanStride -= width * srcPixelStride;
            h = height;

            J2dTraceLn4(J2D_TRACE_VERBOSE,
                        "  sx=%d sy=%d w=%d h=%d",
                        srcInfo.bounds.x1, srcInfo.bounds.y1, width, height);
            J2dTraceLn2(J2D_TRACE_VERBOSE,
                        "  maskoff=%d maskscan=%d",
                        maskoff, maskscan);
            J2dTraceLn2(J2D_TRACE_VERBOSE,
                        "  pixstride=%d scanstride=%d",
                        srcPixelStride, srcScanStride);

            // enqueue parameters
            pBuf[0] = sun_java2d_pipe_BufferedOpCodes_MASK_BLIT;
            pBuf[1] = dstx;
            pBuf[2] = dsty;
            pBuf[3] = width;
            pBuf[4] = height;
            pBuf += 5;
            bpos += 5 * sizeof(jint);

            // apply alpha values from mask to the source tile, and store
            // resulting IntArgbPre pixels into RenderBuffer (there are
            // separate inner loops for the most common source formats)
            switch (srcType) {
            case sun_java2d_pipe_BufferedMaskBlit_ST_INT_ARGB:
                do {
                    jint w = width;
                    do {
                        jubyte pathA = *pMask++;
                        if (!pathA) {
                            pBuf[0] = 0;
                        } else {
                            jint cr, cg, cb, ca;
                            jubyte r, g, b, a;
                            LoadIntArgbTo4ByteArgb(pSrc, c, 0, ca, cr, cg, cb);
                            a = MUL8(ca, pathA);
                            r = MUL8(cr, a);
                            g = MUL8(cg, a);
                            b = MUL8(cb, a);
                            pBuf[0] = (a << 24) | (r << 16) | (g << 8) | b;
                        }
                        pSrc = PtrAddBytes(pSrc, srcPixelStride);
                        pBuf++;
                    } while (--w > 0);
                    pSrc = PtrAddBytes(pSrc, srcScanStride);
                    pMask = PtrAddBytes(pMask, maskscan);
                } while (--h > 0);
                break;

            case sun_java2d_pipe_BufferedMaskBlit_ST_INT_ARGB_PRE:
                do {
                    jint w = width;
                    do {
                        jubyte pathA = *pMask++;
                        if (!pathA) {
                            pBuf[0] = 0;
                        } else if (pathA == 0xff) {
                            pBuf[0] = pSrc[0];
                        } else {
                            jubyte r, g, b, a;
                            a = MUL8((pSrc[0] >> 24) & 0xff, pathA);
                            r = MUL8((pSrc[0] >> 16) & 0xff, pathA);
                            g = MUL8((pSrc[0] >>  8) & 0xff, pathA);
                            b = MUL8((pSrc[0] >>  0) & 0xff, pathA);
                            pBuf[0] = (a << 24) | (r << 16) | (g << 8) | b;
                        }
                        pSrc = PtrAddBytes(pSrc, srcPixelStride);
                        pBuf++;
                    } while (--w > 0);
                    pSrc = PtrAddBytes(pSrc, srcScanStride);
                    pMask = PtrAddBytes(pMask, maskscan);
                } while (--h > 0);
                break;

            case sun_java2d_pipe_BufferedMaskBlit_ST_INT_RGB:
                do {
                    jint w = width;
                    do {
                        jubyte pathA = *pMask++;
                        if (!pathA) {
                            pBuf[0] = 0;
                        } else {
                            jint cr, cg, cb;
                            jubyte r, g, b, a;
                            LoadIntRgbTo3ByteRgb(pSrc, c, 0, cr, cg, cb);
                            a = pathA;
                            r = MUL8(cr, a);
                            g = MUL8(cg, a);
                            b = MUL8(cb, a);
                            pBuf[0] = (a << 24) | (r << 16) | (g << 8) | b;
                        }
                        pSrc = PtrAddBytes(pSrc, srcPixelStride);
                        pBuf++;
                    } while (--w > 0);
                    pSrc = PtrAddBytes(pSrc, srcScanStride);
                    pMask = PtrAddBytes(pMask, maskscan);
                } while (--h > 0);
                break;

            case sun_java2d_pipe_BufferedMaskBlit_ST_INT_BGR:
                do {
                    jint w = width;
                    do {
                        jubyte pathA = *pMask++;
                        if (!pathA) {
                            pBuf[0] = 0;
                        } else {
                            jint cr, cg, cb;
                            jubyte r, g, b, a;
                            LoadIntBgrTo3ByteRgb(pSrc, c, 0, cr, cg, cb);
                            a = pathA;
                            r = MUL8(cr, a);
                            g = MUL8(cg, a);
                            b = MUL8(cb, a);
                            pBuf[0] = (a << 24) | (r << 16) | (g << 8) | b;
                        }
                        pSrc = PtrAddBytes(pSrc, srcPixelStride);
                        pBuf++;
                    } while (--w > 0);
                    pSrc = PtrAddBytes(pSrc, srcScanStride);
                    pMask = PtrAddBytes(pMask, maskscan);
                } while (--h > 0);
                break;

            default:
                // should not get here, just no-op...
                break;
            }

            // increment current byte position
            bpos += width * height * sizeof(jint);
        }
Exemplo n.º 4
0
HRESULT
D3DBufImgOps_EnableLookupOp(D3DContext *d3dc,
                            jboolean nonPremult, jboolean shortData,
                            jint numBands, jint bandLength, jint offset,
                            void *tableValues)
{
    HRESULT res;
    IDirect3DDevice9 *pd3dDevice;
    D3DResource *pLutTexRes;
    IDirect3DTexture9 *pLutTex;
    int bytesPerElem = (shortData ? 2 : 1);
    jfloat foffsets[4];
    void *bands[4];
    int i;
    jint flags = 0;

    J2dTraceLn4(J2D_TRACE_INFO,
                "D3DBufImgOps_EnableLookupOp: short=%d num=%d len=%d off=%d",
                shortData, numBands, bandLength, offset);

    RETURN_STATUS_IF_NULL(d3dc, E_FAIL);

    d3dc->UpdateState(STATE_CHANGE);

    // choose the appropriate shader, depending on the source image
    // and the number of bands involved
    if (numBands != 4) {
        flags |= LOOKUP_USE_SRC_ALPHA;
    }
    if (nonPremult) {
        flags |= LOOKUP_NON_PREMULT;
    }

    // locate/enable the shader program for the given flags
    res = d3dc->EnableLookupProgram(flags);
    RETURN_STATUS_IF_FAILED(res);

    // update the "uniform" offset value
    for (i = 0; i < 4; i++) {
        foffsets[i] = offset / 255.0f;
    }
    pd3dDevice = d3dc->Get3DDevice();
    pd3dDevice->SetPixelShaderConstantF(0, foffsets, 1);

    res = d3dc->GetResourceManager()->GetLookupOpLutTexture(&pLutTexRes);
    RETURN_STATUS_IF_FAILED(res);
    pLutTex = pLutTexRes->GetTexture();

    // update the lookup table with the user-provided values
    if (numBands == 1) {
        // replicate the single band for R/G/B; alpha band is unused
        for (i = 0; i < 3; i++) {
            bands[i] = tableValues;
        }
        bands[3] = NULL;
    } else if (numBands == 3) {
        // user supplied band for each of R/G/B; alpha band is unused
        for (i = 0; i < 3; i++) {
            bands[i] = PtrAddBytes(tableValues, i*bandLength*bytesPerElem);
        }
        bands[3] = NULL;
    } else if (numBands == 4) {
        // user supplied band for each of R/G/B/A
        for (i = 0; i < 4; i++) {
            bands[i] = PtrAddBytes(tableValues, i*bandLength*bytesPerElem);
        }
    }

    // upload the bands one row at a time into our lookup table texture
    D3DLOCKED_RECT lockedRect;
    res = pLutTex->LockRect(0, &lockedRect, NULL, D3DLOCK_NOSYSLOCK);
    RETURN_STATUS_IF_FAILED(res);

    jushort *pBase = (jushort*)lockedRect.pBits;
    for (i = 0; i < 4; i++) {
        jushort *pDst;
        if (bands[i] == NULL) {
            continue;
        }
        pDst = pBase + (i * 256);
        if (shortData) {
            memcpy(pDst, bands[i], bandLength*sizeof(jushort));
        } else {
            int j;
            jubyte *pSrc = (jubyte *)bands[i];
            for (j = 0; j < bandLength; j++) {
                pDst[j] = (jushort)(pSrc[j] << 8);
            }
        }
    }
    pLutTex->UnlockRect(0);

    // bind the lookup table to texture unit 1 and enable texturing
    res = d3dc->SetTexture(pLutTex, 1);
    pd3dDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
    pd3dDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
    pd3dDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    pd3dDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    return res;
}