void
OGLPaints_SetColor(OGLContext *oglc, jint pixel)
{
    jubyte r, g, b, a;

    J2dTraceLn1(J2D_TRACE_INFO, "OGLPaints_SetColor: pixel=%08x", pixel);

    RETURN_IF_NULL(oglc);

    // glColor*() is allowed within glBegin()/glEnd() pairs, so
    // no need to reset the current op state here unless the paint
    // state really needs to be changed
    if (oglc->paintState > sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR) {
        OGLPaints_ResetPaint(oglc);
    }

    // store the raw (unmodified) pixel value, which may be used for
    // special operations later
    oglc->pixel = pixel;

    if (oglc->compState != sun_java2d_SunGraphics2D_COMP_XOR) {
        r = (jubyte)(pixel >> 16);
        g = (jubyte)(pixel >>  8);
        b = (jubyte)(pixel >>  0);
        a = (jubyte)(pixel >> 24);

        J2dTraceLn4(J2D_TRACE_VERBOSE,
                    "  updating color: r=%02x g=%02x b=%02x a=%02x",
                    r, g, b, a);
    } else {
Esempio n. 2
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    getCurrentDisplayModeNative
 * Signature: (I)Ljava/awt/DisplayMode;
 */
JNIEXPORT jobject JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_getCurrentDisplayModeNative
  (JNIEnv *env, jclass gdc, jint gdiScreen)
{
    D3DPipelineManager *pMgr;
    IDirect3D9 *pd3d9;
    jobject ret = NULL;
    D3DDISPLAYMODE mode;
    UINT adapter;

    J2dTraceLn(J2D_TRACE_INFO, "D3DGD_getCurrentDisplayModeNative");

    RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), NULL);
    RETURN_STATUS_IF_NULL(pd3d9 = pMgr->GetD3DObject(), NULL);
    adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);

    if (SUCCEEDED(pd3d9->GetAdapterDisplayMode(adapter, &mode))) {
        int bitDepth = -1;
        // these are the only three valid screen formats
        switch (mode.Format) {
            case D3DFMT_X8R8G8B8: bitDepth = 32; break;
            case D3DFMT_R5G6B5:
            case D3DFMT_X1R5G5B5: bitDepth = 16; break;
        }
        J2dTraceLn4(J2D_TRACE_VERBOSE,
                    "  current dm: %dx%dx%d@%d",
                    mode.Width, mode.Height, bitDepth, mode.RefreshRate);
        ret = CreateDisplayMode(env, mode.Width, mode.Height, bitDepth,
                                mode.RefreshRate);
    }
    return ret;
}
Esempio n. 3
0
/**
 * Sets the OpenGL scissor bounds to the provided rectangular clip bounds.
 */
void
OGLContext_SetRectClip(OGLContext *oglc, OGLSDOps *dstOps,
                       jint x1, jint y1, jint x2, jint y2)
{
    jint width = x2 - x1;
    jint height = y2 - y1;

    J2dTraceLn4(J2D_TRACE_INFO,
                "OGLContext_SetRectClip: x=%d y=%d w=%d h=%d",
                x1, y1, width, height);

    RETURN_IF_NULL(dstOps);
    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    if ((width < 0) || (height < 0)) {
        // use an empty scissor rectangle when the region is empty
        width = 0;
        height = 0;
    }

    j2d_glDisable(GL_DEPTH_TEST);
    j2d_glEnable(GL_SCISSOR_TEST);

    // the scissor rectangle is specified using the lower-left
    // origin of the clip region (in the framebuffer's coordinate
    // space), so we must account for the x/y offsets of the
    // destination surface
    j2d_glScissor(dstOps->xOffset + x1,
                  dstOps->yOffset + dstOps->height - (y1 + height),
                  width, height);
}
Esempio n. 4
0
/**
 * Initializes the viewport and projection matrix, effectively positioning
 * the origin at the top-left corner of the surface.  This allows Java 2D
 * coordinates to be passed directly to OpenGL, which is typically based on
 * a bottom-right coordinate system.  This method also sets the appropriate
 * read and draw buffers.
 */
static void
OGLContext_SetViewport(OGLSDOps *srcOps, OGLSDOps *dstOps)
{
    jint width = dstOps->width;
    jint height = dstOps->height;

    J2dTraceLn4(J2D_TRACE_INFO,
                "OGLContext_SetViewport: w=%d h=%d read=%s draw=%s",
                width, height,
                OGLC_ACTIVE_BUFFER_NAME(srcOps->activeBuffer),
                OGLC_ACTIVE_BUFFER_NAME(dstOps->activeBuffer));

    // set the viewport and projection matrix
    j2d_glViewport(dstOps->xOffset, dstOps->yOffset,
                   (GLsizei)width, (GLsizei)height);
    j2d_glMatrixMode(GL_PROJECTION);
    j2d_glLoadIdentity();
    j2d_glOrtho(0.0, (GLdouble)width, (GLdouble)height, 0.0, -1.0, 1.0);

    // set the active read and draw buffers
    j2d_glReadBuffer(srcOps->activeBuffer);
    j2d_glDrawBuffer(dstOps->activeBuffer);

    // set the color mask to enable alpha channel only when necessary
    j2d_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, (GLboolean)!dstOps->isOpaque);
}
Esempio n. 5
0
/*
 * Class:     sun_java2d_windows_GDIRenderer
 * Method:    doFillPoly
 * Signature: (Lsun/java2d/windows/GDIWindowSurfaceData;Lsun/java2d/pipe/Region;Ljava/awt/Composite;III[I[II)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIRenderer_doFillPoly
    (JNIEnv *env, jobject wr,
     jobject sData,
     jobject clip, jobject comp, jint color,
     jint transx, jint transy,
     jintArray xpointsarray, jintArray ypointsarray,
     jint npoints)
{
    J2dTraceLn(J2D_TRACE_INFO, "GDIRenderer_doFillPoly");
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  color=0x%x transx=%-4d transy=%-4d npoints=%-4d",
                color, transx, transy, npoints);
    if (JNU_IsNull(env, xpointsarray) || JNU_IsNull(env, ypointsarray)) {
        JNU_ThrowNullPointerException(env, "coordinate array");
        return;
    }
    if (env->GetArrayLength(xpointsarray) < npoints ||
        env->GetArrayLength(ypointsarray) < npoints)
    {
        JNU_ThrowArrayIndexOutOfBoundsException(env, "coordinate array");
        return;
    }
    if (npoints < 3) {
        // Fix for 4067534 - assertion failure in 1.3.1 for degenerate polys
        // Not enough points for a triangle.
        // Note that this would be ignored later anyway, but returning
        // here saves us from mistakes in TransformPoly and seeing bad
        // return values from the Windows Polyline function.
        return;
    }

    GDIWinSDOps *wsdo = GDIWindowSurfaceData_GetOps(env, sData);
    if (wsdo == NULL) {
        return;
    }

    POINT tmpPts[POLYTEMPSIZE], *pPoints;
    jint *xpoints = (jint *) env->GetPrimitiveArrayCritical(xpointsarray, NULL);
    jint *ypoints = (jint *) env->GetPrimitiveArrayCritical(ypointsarray, NULL);
    pPoints = TransformPoly(xpoints, ypoints, transx, transy,
                            tmpPts, &npoints, FALSE, FALSE);
    env->ReleasePrimitiveArrayCritical(xpointsarray, xpoints, JNI_ABORT);
    env->ReleasePrimitiveArrayCritical(ypointsarray, ypoints, JNI_ABORT);
    if (pPoints == NULL) {
        return;
    }

    HDC hdc = wsdo->GetDC(env, wsdo, BRUSHONLY, NULL, clip, comp, color);
    if (hdc == NULL) {
        return;
    }
    ::SetPolyFillMode(hdc, ALTERNATE);
    ::Polygon(hdc, pPoints, npoints);
    wsdo->ReleaseDC(env, wsdo, hdc);
    if (pPoints != tmpPts) {
        free(pPoints);
    }
}
Esempio n. 6
0
/*
 * Class:     sun_java2d_windows_GDIRenderer
 * Method:    devCopyArea
 * Signature: (Lsun/java2d/windows/GDIWindowSurfaceData;IIIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIRenderer_devCopyArea
    (JNIEnv *env, jobject wr,
     jobject wsd,
     jint srcx, jint srcy,
     jint dx, jint dy,
     jint width, jint height)
{
    GDIWinSDOps *wsdo = GDIWindowSurfaceData_GetOps(env, wsd);
    J2dTraceLn(J2D_TRACE_INFO, "GDIWindowSurfaceData_devCopyArea");
    J2dTraceLn4(J2D_TRACE_VERBOSE, "   srcx=%-4d srcy=%-4d dx=%-4d dy=%-4d",
                srcx, srcy, dx, dy);
    J2dTraceLn2(J2D_TRACE_VERBOSE, "     w=%-4d h=%-4d", width, height);
    if (wsdo == NULL) {
        return;
    }
    if (wsdo->invalid) {
        SurfaceData_ThrowInvalidPipeException(env,
            "GDIRenderer_devCopyArea: invalid surface data");
        return;
    }

    HDC hDC = wsdo->GetDC(env, wsdo, 0, NULL, NULL, NULL, 0);
    if (hDC == NULL) {
        return;
    }

    RECT r;
    ::SetRect(&r, srcx, srcy, srcx + width, srcy + height);
    HRGN rgnUpdate = ::CreateRectRgn(0, 0, 0, 0);
    VERIFY(::ScrollDC(hDC, dx, dy, &r, NULL, rgnUpdate, NULL));

    // ScrollDC invalidates the part of the source rectangle that
    // is outside of the destination rectangle on the assumption
    // that you wanted to "move" the pixels from source to dest,
    // and so now you will want to paint new pixels in the source.
    // Since our copyarea operation involves no such semantics we
    // are only interested in the part of the update region that
    // corresponds to unavailable source pixels - i.e. the part
    // that falls within the destination rectangle.

    // The update region will be in client relative coordinates
    // but the destination rect will be in window relative coordinates
    ::OffsetRect(&r, dx-wsdo->insets.left, dy-wsdo->insets.top);
    HRGN rgnDst = ::CreateRectRgnIndirect(&r);
    int result = ::CombineRgn(rgnUpdate, rgnUpdate, rgnDst, RGN_AND);

    // Invalidate the exposed area.
    if (result != NULLREGION) {
        ::InvalidateRgn(wsdo->window, rgnUpdate, TRUE);
    }
    ::DeleteObject(rgnUpdate);
    ::DeleteObject(rgnDst);

    wsdo->ReleaseDC(env, wsdo, hDC);
}
Esempio n. 7
0
HRESULT D3DPIPELINE_API
D3DRenderer_DrawLine(D3DContext *d3dc,
                     jint x1, jint y1, jint x2, jint y2)
{
    J2dTraceLn4(J2D_TRACE_INFO,
                "D3DRenderer_doDrawLineD3D x1=%-4d y1=%-4d x2=%-4d y2=%-4d",
                x1, y1, x2, y2);
    d3dc->BeginScene(STATE_RENDEROP);
    return d3dc->pVCacher->DrawLine(x1, y1, x2, y2);
}
Esempio n. 8
0
HRESULT D3DPIPELINE_API
D3DRenderer_FillRect(D3DContext *d3dc,
                     jint x, jint y, jint w, jint h)
{
    J2dTraceLn4(J2D_TRACE_INFO,
               "D3DRenderer_FillRect x=%-4d y=%-4d w=%-4d h=%-4d",
                x, y, w, h);

    d3dc->BeginScene(STATE_RENDEROP);
    return d3dc->pVCacher->FillRect(x, y, x + w, y + h);
}
Esempio n. 9
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    enumDisplayModesNative
 * Signature: (ILjava/util/ArrayList;)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_enumDisplayModesNative
  (JNIEnv *env, jclass gdc, jint gdiScreen, jobject arrayList)
{
    D3DPipelineManager *pMgr;
    IDirect3D9 *pd3d9;
    jobject ret = NULL;
    D3DDISPLAYMODE mode;
    UINT formatNum, modeNum, modesCount;
    UINT adapter;
    // EnumAdapterModes treats 555 and 565 formats as equivalents
    static D3DFORMAT formats[] =
        { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5 };

    J2dTraceLn(J2D_TRACE_INFO, "D3DGD_enumDisplayModesNative");

    RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance());
    RETURN_IF_NULL(pd3d9 = pMgr->GetD3DObject());
    adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);

    for (formatNum = 0; formatNum < 3; formatNum++) {
        modesCount = pd3d9->GetAdapterModeCount(adapter, formats[formatNum]);
        for (modeNum = 0; modeNum < modesCount; modeNum++) {
            if (SUCCEEDED(pd3d9->EnumAdapterModes(adapter, formats[formatNum],
                                                  modeNum, &mode)))
            {
                int bitDepth = -1;
                // these are the only three valid screen formats,
                // 30-bit is returned as X8R8G8B8
                switch (mode.Format) {
                    case D3DFMT_X8R8G8B8: bitDepth = 32; break;
                    case D3DFMT_R5G6B5:
                    case D3DFMT_X1R5G5B5: bitDepth = 16; break;
                }
                J2dTraceLn4(J2D_TRACE_VERBOSE, "  found dm: %dx%dx%d@%d",
                            mode.Width, mode.Height, bitDepth,mode.RefreshRate);
                addDisplayMode(env, arrayList, mode.Width, mode.Height,
                               bitDepth, mode.RefreshRate);
            }
        }
    }
}
Esempio n. 10
0
/**
 * 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.
 *
 * When the source paint is a Color, we can simply use the GL_MODULATE
 * function to multiply the current color (already premultiplied with the
 * extra alpha value from the AlphaComposite) with the alpha value from
 * the mask texture tile.  In picture form, this process looks like:
 *
 *                        A     R    G     B
 *     primary color      Pa    Pr   Pg    Pb    (modulated with...)
 *     texture unit 0     Ca    Ca   Ca    Ca
 *     ---------------------------------------
 *     resulting color    Ra    Rr   Rg    Rb
 *
 * where:
 *     Px = current color (already premultiplied by extra alpha)
 *     Cx = coverage value from mask tile
 *     Rx = resulting color/alpha component
 *
 * When the source paint is not a Color, it means that we are rendering with
 * a complex paint (e.g. GradientPaint, TexturePaint).  In this case, we
 * rely on the GL_ARB_multitexture extension to effectively multiply the
 * paint fragments (autogenerated on texture unit 1, see the
 * OGLPaints_Set{Gradient,Texture,etc}Paint() methods for more details)
 * with the coverage values from the mask texture tile (provided on texture
 * unit 0), all of which is multiplied with the current color value (which
 * contains the extra alpha value).  In picture form:
 *
 *                        A     R    G     B
 *     primary color      Ea    Ea   Ea    Ea    (modulated with...)
 *     texture unit 0     Ca    Ca   Ca    Ca    (modulated with...)
 *     texture unit 1     Pa    Pr   Pg    Pb
 *     ---------------------------------------
 *     resulting color    Ra    Rr   Rg    Rb
 *
 * where:
 *     Ea = extra alpha
 *     Cx = coverage value from mask tile
 *     Px = gradient/texture paint color (generated for each fragment)
 *     Rx = resulting color/alpha component
 *
 * 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
 */
void
OGLMaskFill_MaskFill(OGLContext *oglc,
                     jint x, jint y, jint w, jint h,
                     jint maskoff, jint maskscan, jint masklen,
                     unsigned char *pMask)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLMaskFill_MaskFill");

    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_MASK_OP);

    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);

    {
        jint tw, th, x0;
        jint sx1, sy1, sx2, sy2;
        jint sx, sy, sw, sh;

        x0 = x;
        tw = OGLVC_MASK_CACHE_TILE_WIDTH;
        th = OGLVC_MASK_CACHE_TILE_HEIGHT;
        sx1 = maskoff % maskscan;
        sy1 = maskoff / maskscan;
        sx2 = sx1 + w;
        sy2 = sy1 + h;

        for (sy = sy1; sy < sy2; sy += th, y += th) {
            x = x0;
            sh = ((sy + th) > sy2) ? (sy2 - sy) : th;

            for (sx = sx1; sx < sx2; sx += tw, x += tw) {
                sw = ((sx + tw) > sx2) ? (sx2 - sx) : tw;

                OGLVertexCache_AddMaskQuad(oglc,
                                           sx, sy, x, y, sw, sh,
                                           maskscan, pMask);
            }
        }
    }
}
Esempio n. 11
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    configDisplayModeNative
 * Signature: (IJIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_configDisplayModeNative
  (JNIEnv *env, jclass gdc, jint gdiScreen, jlong window,
   jint width, jint height, jint bitDepth, jint refreshRate)
{
    HRESULT res;
    D3DPipelineManager *pMgr;
    D3DContext *pCtx;
    D3DPRESENT_PARAMETERS newParams, *pCurParams;
    UINT adapter;

    J2dTraceLn(J2D_TRACE_INFO, "D3DGD_configDisplayModeNative");

    RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance());
    adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);

    if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {
        D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
        return;
    }

    pCurParams = pCtx->GetPresentationParams();

    newParams = *pCurParams;
    newParams.BackBufferWidth = width;
    newParams.BackBufferHeight = height;
    newParams.FullScreen_RefreshRateInHz = refreshRate;
    newParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
    // we leave the swap effect so that it's more likely
    // to be the one user selected initially
//    newParams.SwapEffect = D3DSWAPEFFECT_DISCARD;

    if (bitDepth == 32) {
        newParams.BackBufferFormat = D3DFMT_X8R8G8B8;
    } else if (bitDepth == 16) {
        UINT modeNum;
        D3DDISPLAYMODE mode;
        IDirect3D9 *pd3d9;
        UINT modesCount;

        RETURN_IF_NULL(pd3d9 = pMgr->GetD3DObject());

        modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_R5G6B5);
        if (modesCount == 0) {
            modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_X1R5G5B5);
        }

        newParams.BackBufferFormat = D3DFMT_UNKNOWN;
        for (modeNum = 0; modeNum < modesCount; modeNum++) {
            if (SUCCEEDED(pd3d9->EnumAdapterModes(adapter, D3DFMT_R5G6B5,
                                                  modeNum, &mode)))
            {
                if (mode.Width == width && mode.Height == height &&
                    mode.RefreshRate == refreshRate)
                {
                    // prefer 565 over 555
                    if (mode.Format == D3DFMT_R5G6B5) {
                        newParams.BackBufferFormat = D3DFMT_R5G6B5;
                        break;
                    } else if (mode.Format == D3DFMT_X1R5G5B5) {
                        newParams.BackBufferFormat = D3DFMT_X1R5G5B5;
                    }
                }
            }
        }
        if (newParams.BackBufferFormat == D3DFMT_UNKNOWN) {
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                          "D3DGD_configDisplayModeNative: no 16-bit formats");
            return;
        }
    } else {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
                       "D3DGD_configDisplayModeNative: unsupported depth: %d",
                       bitDepth);
        return;
    }

    J2dTraceLn4(J2D_TRACE_VERBOSE, "  changing to dm: %dx%dx%d@%d",
                newParams.BackBufferWidth, newParams.BackBufferHeight,
                bitDepth, refreshRate);
    J2dTraceLn1(J2D_TRACE_VERBOSE, "  selected backbuffer format: %d",
                newParams.BackBufferFormat);

    res = pCtx->ConfigureContext(&newParams);
    if (SUCCEEDED(res)) {
        // the full screen window doesn't receive WM_SIZE event when
        // the display mode changes (it does get resized though) so we need to
        // generate the event ourselves
        ::SendMessage(newParams.hDeviceWindow, WM_SIZE, width, height);
    }
    D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
}
Esempio n. 12
0
HRESULT
D3DResourceManager::CreateSwapChain(HWND hWnd, UINT numBuffers,
                                    UINT width, UINT height,
                                    D3DSWAPEFFECT swapEffect,
                                    UINT presentationInterval,
                                    D3DResource ** ppSwapChainResource)
{
    HRESULT res;
    IDirect3DDevice9 *pd3dDevice;
    IDirect3DSwapChain9 *pSwapChain = NULL;
    D3DPRESENT_PARAMETERS newParams, *curParams;

    J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateSwapChain");
    J2dTraceLn4(J2D_TRACE_VERBOSE, "  w=%d h=%d hwnd=%x numBuffers=%d",
                width, height, hWnd, numBuffers);

    if (pCtx == NULL || ppSwapChainResource == NULL ||
        (pd3dDevice = pCtx->Get3DDevice()) == NULL)
    {
        return E_FAIL;
    }
    RETURN_STATUS_IF_FAILED(res = pd3dDevice->TestCooperativeLevel());

    curParams = pCtx->GetPresentationParams();

    if (curParams->Windowed == FALSE) {
        // there's a single swap chain in full-screen mode, use it if
        // it fits our parameters, reset the device otherwise
        if (curParams->BackBufferCount != numBuffers ||
            curParams->SwapEffect != swapEffect ||
            curParams->PresentationInterval != presentationInterval)
        {
            newParams = *curParams;
            newParams.BackBufferCount = numBuffers;
            newParams.SwapEffect = swapEffect;
            newParams.PresentationInterval = presentationInterval;

            res = pCtx->ConfigureContext(&newParams);
            RETURN_STATUS_IF_FAILED(res);
            // this reset will not have released the device, so our pd3dDevice
            // is still valid, but to be on a safe side, reset it
            pd3dDevice = pCtx->Get3DDevice();
        }
        res = pd3dDevice->GetSwapChain(0, &pSwapChain);
    } else {
        ZeroMemory(&newParams, sizeof(D3DPRESENT_PARAMETERS));
        newParams.BackBufferWidth = width;
        newParams.BackBufferHeight = height;
        newParams.hDeviceWindow = hWnd;
        newParams.Windowed = TRUE;
        newParams.BackBufferCount = numBuffers;
        newParams.SwapEffect = swapEffect;
        newParams.PresentationInterval = presentationInterval;

        res = pd3dDevice->CreateAdditionalSwapChain(&newParams, &pSwapChain);
    }

    if (SUCCEEDED(res)) {
        J2dTraceLn1(J2D_TRACE_VERBOSE,"  created swap chain: 0x%x ",pSwapChain);
        *ppSwapChainResource = new D3DResource(pSwapChain);
        res = AddResource(*ppSwapChainResource);
    } else {
        DebugPrintD3DError(res, "D3DRM::CreateSwapChain failed");
        *ppSwapChainResource = NULL;
    }
    return res;
}
Esempio n. 13
0
HRESULT
D3DResourceManager::CreateTexture(UINT width, UINT height,
                                  BOOL isRTT, BOOL isOpaque,
                                  D3DFORMAT *pFormat, DWORD dwUsage,
                                  D3DResource **ppTextureResource)
{
    D3DPOOL pool;
    D3DFORMAT format;
    HRESULT res;
    IDirect3DDevice9 *pd3dDevice;

    J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateTexture");
    J2dTraceLn4(J2D_TRACE_VERBOSE, "  w=%d h=%d isRTT=%d isOpaque=%d",
                width, height, isRTT, isOpaque);

    if (ppTextureResource == NULL || pCtx == NULL ||
        (pd3dDevice = pCtx->Get3DDevice()) == NULL)
    {
        return E_FAIL;
    }
    if (FAILED(res = pd3dDevice->TestCooperativeLevel())) {
        return res;
    }

    if (pFormat != NULL && *pFormat != D3DFMT_UNKNOWN) {
        format = *pFormat;
    } else {
        if (isOpaque) {
            format = D3DFMT_X8R8G8B8;
        } else {
            format = D3DFMT_A8R8G8B8;
        }
    }

    if (isRTT) {
        dwUsage = D3DUSAGE_RENDERTARGET;
        pool = D3DPOOL_DEFAULT;
    } else {
        if (dwUsage == D3DUSAGE_DYNAMIC && !pCtx->IsDynamicTextureSupported()) {
            dwUsage = 0;
        }
        if (dwUsage == D3DUSAGE_DYNAMIC) {
            pool = D3DPOOL_DEFAULT;
        } else {
            pool = pCtx->IsHWRasterizer() ?
                D3DPOOL_MANAGED : D3DPOOL_SYSTEMMEM;
        }
    }

    if (pCtx->IsPow2TexturesOnly()) {
          UINT w, h;
          for (w = 1; width  > w; w <<= 1);
          for (h = 1; height > h; h <<= 1);
          width = w;
          height = h;
    }
    if (pCtx->IsSquareTexturesOnly()) {
        if (width > height) {
            height = width;
        } else {
            width = height;
        }
    }

    IDirect3DTexture9 *pTexture = NULL;
    res = pd3dDevice->CreateTexture(width, height, 1/*levels*/, dwUsage,
                                    format, pool, &pTexture, 0);
    if (SUCCEEDED(res)) {
        J2dTraceLn1(J2D_TRACE_VERBOSE, "  created texture: 0x%x", pTexture);
        *ppTextureResource = new D3DResource((IDirect3DResource9*)pTexture);
        res = AddResource(*ppTextureResource);
    } else {
        DebugPrintD3DError(res, "D3DRM::CreateTexture failed");
        *ppTextureResource = NULL;
        format = D3DFMT_UNKNOWN;
    }

    if (pFormat != NULL) {
        *pFormat = format;
    }

    return res;
}
Esempio n. 14
0
/*
 * Class:     sun_java2d_d3d_D3DSurfaceData
 * Method:    initOffScreenSurface
 * Signature: (JJJIIII)I
 */
JNIEXPORT jint JNICALL
Java_sun_java2d_d3d_D3DSurfaceData_initOffScreenSurface
    (JNIEnv *env, jobject sData,
     jlong pCtx,
     jlong pData, jlong parentPdata,
     jint width, jint height,
     jint d3dSurfaceType, jint screen)
{
    Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
    D3DContext *pd3dc = (D3DContext *)jlong_to_ptr(pCtx);

    J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initOffScreenSurface");
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  width=%-4d height=%-4d type=%-3d scr=%-3d",
                width, height, d3dSurfaceType, screen);

    // REMIND: ideally this should be done in initOps
    if (d3dSurfaceType == D3D_ATTACHED_SURFACE) {
        wsdo->sdOps.Dispose = Win32BBSD_Dispose;
    }

    if (init_D3DSDO(env, wsdo, width, height,
                    d3dSurfaceType, screen) == JNI_FALSE)
    {
        SurfaceData_ThrowInvalidPipeException(env,
            "Can't create offscreen surface");
        return PF_INVALID;
    }

    HMONITOR hMon = (HMONITOR)wsdo->device->GetMonitor();
    DDrawObjectStruct *ddInstance = GetDDInstanceForDevice(hMon);
    if (!ddInstance || !ddInstance->valid || !pd3dc) {
        return PF_INVALID;
    }

    if (d3dSurfaceType == D3D_ATTACHED_SURFACE) {
        // REMIND: still using the old path. ideally the creation of attached
        // surface shoudld be done in the same way as other types of surfaces,
        // that is, in D3DContext::CreateSurface, but we really don't use
        // anything from D3DContext to get an attached surface, so this
        // was left here.

        Win32SDOps *wsdo_parent = (Win32SDOps *)jlong_to_ptr(parentPdata);
        // we're being explicit here: requesting backbuffer, and render target
        DDrawSurface* pNew = wsdo_parent->lpSurface == NULL ?
            NULL :
            wsdo_parent->lpSurface->
                GetDDAttachedSurface(DDSCAPS_BACKBUFFER|DDSCAPS_3DDEVICE);
        if (pNew == NULL ||
            FAILED(pd3dc->AttachDepthBuffer(pNew->GetDXSurface())))
        {
            J2dRlsTraceLn1(J2D_TRACE_ERROR,
                           "D3DSD_initSurface: GetAttachedSurface for parent"\
                           " wsdo_parent->lpSurface=0x%x failed",
                           wsdo_parent->lpSurface);
            if (pNew != NULL) {
                delete pNew;
            }
            SurfaceData_ThrowInvalidPipeException(env,
                "Can't create attached offscreen surface");
            return PF_INVALID;
        }

        wsdo->lpSurface = pNew;
        wsdo->ddInstance = ddInstance;
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "D3DSD_initSurface: created attached surface: "\
                    "wsdo->lpSurface=0x%x for parent "\
                    "wsdo_parent->lpSurface=0x%x",
                    wsdo->lpSurface, wsdo_parent->lpSurface);
        // we don't care about pixel format for non-texture surfaces
        return PF_INVALID;
    }

    DXSurface *dxSurface = NULL;
    jint pf = PF_INVALID;
    HRESULT res;
    if (SUCCEEDED(res = pd3dc->CreateSurface(env, wsdo->w, wsdo->h,
                                             wsdo->depth, wsdo->transparency,
                                             d3dSurfaceType,
                                             &dxSurface, &pf)))
    {
        // REMIND: put all the error-handling stuff here from
        // DDCreateOffScreenSurface
        wsdo->lpSurface = new DDrawSurface(ddInstance->ddObject, dxSurface);
        wsdo->surfacePuntData.lpSurfaceVram = wsdo->lpSurface;
        wsdo->ddInstance = ddInstance;
        // the dimensions of the surface may be adjusted in case of
        // textures
        wsdo->w = dxSurface->GetWidth();
        wsdo->h = dxSurface->GetHeight();
        J2dTraceLn1(J2D_TRACE_VERBOSE,
                    "D3DSurfaceData_initSurface: created surface: "\
                    "wsdo->lpSurface=0x%x", wsdo->lpSurface);
    } else {
        DebugPrintDirectDrawError(res,
                                  "D3DSurfaceData_initSurface: "\
                                  "CreateSurface failed");
        // REMIND: should use some other way to signal that
        // surface creation was unsuccessful
        SurfaceData_ThrowInvalidPipeException(env,
                                              "Can't create offscreen surf");
    }
    return pf;
}
/**
 * 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);
        }
Esempio n. 16
0
/*
 * Class:     sun_java2d_windows_GDIRenderer
 * Method:    doShape
 * Signature:  (Lsun/java2d/windows/GDIWindowSurfaceData;Lsun/java2d/pipe/Region;
 *              Ljava/awt/Composite;IIILjava/awt/geom/Path2D.Float;Z)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIRenderer_doShape
    (JNIEnv *env, jobject wr,
     jobject sData,
     jobject clip, jobject comp, jint color,
     jint transX, jint transY,
     jobject p2df, jboolean isfill)
{
    J2dTraceLn(J2D_TRACE_INFO, "GDIRenderer_doShape");
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  color=0x%x transx=%-4d transy=%-4d isfill=%-4d",
                color, transX, transY, isfill);
    GDIWinSDOps *wsdo = GDIWindowSurfaceData_GetOps(env, sData);
    if (wsdo == NULL) {
        return;
    }

    jarray typesarray = (jarray) env->GetObjectField(p2df, path2DTypesID);
    jarray coordsarray = (jarray) env->GetObjectField(p2df,
                                                      path2DFloatCoordsID);
    if (coordsarray == NULL) {
        JNU_ThrowNullPointerException(env, "coordinates array");
        return;
    }
    jint numtypes = env->GetIntField(p2df, path2DNumTypesID);
    if (env->GetArrayLength(typesarray) < numtypes) {
        JNU_ThrowArrayIndexOutOfBoundsException(env, "types array");
        return;
    }
    jint maxcoords = env->GetArrayLength(coordsarray);
    jint rule = env->GetIntField(p2df, path2DWindingRuleID);

    HDC hdc = wsdo->GetDC(env, wsdo, (isfill ? BRUSH : PEN), NULL,
                          clip, comp, color);
    if (hdc == NULL) {
        return;
    }
    ::SetPolyFillMode(hdc, (rule == java_awt_geom_PathIterator_WIND_NON_ZERO
                            ? WINDING : ALTERNATE));
    ::BeginPath(hdc);
    jbyte *types = (jbyte *) env->GetPrimitiveArrayCritical(typesarray,
                                                            NULL);
    jfloat *coords = (jfloat *) env->GetPrimitiveArrayCritical(coordsarray,
                                                               NULL);
    int index = 0;
    BOOL ok = TRUE;
    BOOL isempty = TRUE;
    BOOL isapoint = TRUE;
    int mx = 0, my = 0, x1 = 0, y1 = 0;
    POINT ctrlpts[3];
    for (int i = 0; ok && i < numtypes; i++) {
        switch (types[i]) {
        case java_awt_geom_PathIterator_SEG_MOVETO:
            if (!isfill && !isempty) {
                // Fix for 4298688 - draw(Line) omits last pixel
                // Windows omits the last pixel of a path when stroking.
                // Fix up the last segment of the previous subpath by
                // adding another segment after it that is only 1 pixel
                // long.  The first pixel of that segment will be drawn,
                // but the second pixel is the one that Windows omits.
                ::LineTo(hdc, x1+1, y1);
            }
            if (index + 2 <= maxcoords) {
                mx = x1 = transX + (int) floor(coords[index++]);
                my = y1 = transY + (int) floor(coords[index++]);
                ::MoveToEx(hdc, x1, y1, NULL);
                isempty = TRUE;
                isapoint = TRUE;
            } else {
                ok = FALSE;
            }
            break;
        case java_awt_geom_PathIterator_SEG_LINETO:
            if (index + 2 <= maxcoords) {
                x1 = transX + (int) floor(coords[index++]);
                y1 = transY + (int) floor(coords[index++]);
                ::LineTo(hdc, x1, y1);
                isapoint = isapoint && (x1 == mx && y1 == my);
                isempty = FALSE;
            } else {
                ok = FALSE;
            }
            break;
        case java_awt_geom_PathIterator_SEG_QUADTO:
            if (index + 4 <= maxcoords) {
                ctrlpts[0].x = transX + (int) floor(coords[index++]);
                ctrlpts[0].y = transY + (int) floor(coords[index++]);
                ctrlpts[2].x = transX + (int) floor(coords[index++]);
                ctrlpts[2].y = transY + (int) floor(coords[index++]);
                ctrlpts[1].x = (ctrlpts[0].x * 2 + ctrlpts[2].x) / 3;
                ctrlpts[1].y = (ctrlpts[0].y * 2 + ctrlpts[2].y) / 3;
                ctrlpts[0].x = (ctrlpts[0].x * 2 + x1) / 3;
                ctrlpts[0].y = (ctrlpts[0].y * 2 + y1) / 3;
                x1 = ctrlpts[2].x;
                y1 = ctrlpts[2].y;
                ::PolyBezierTo(hdc, ctrlpts, 3);
                isapoint = isapoint && (x1 == mx && y1 == my);
                isempty = FALSE;
            } else {
                ok = FALSE;
            }
            break;
        case java_awt_geom_PathIterator_SEG_CUBICTO:
            if (index + 6 <= maxcoords) {
                ctrlpts[0].x = transX + (int) floor(coords[index++]);
                ctrlpts[0].y = transY + (int) floor(coords[index++]);
                ctrlpts[1].x = transX + (int) floor(coords[index++]);
                ctrlpts[1].y = transY + (int) floor(coords[index++]);
                ctrlpts[2].x = transX + (int) floor(coords[index++]);
                ctrlpts[2].y = transY + (int) floor(coords[index++]);
                x1 = ctrlpts[2].x;
                y1 = ctrlpts[2].y;
                ::PolyBezierTo(hdc, ctrlpts, 3);
                isapoint = isapoint && (x1 == mx && y1 == my);
                isempty = FALSE;
            } else {
                ok = FALSE;
            }
            break;
        case java_awt_geom_PathIterator_SEG_CLOSE:
            ::CloseFigure(hdc);
            if (x1 != mx || y1 != my) {
                x1 = mx;
                y1 = my;
                ::MoveToEx(hdc, x1, y1, NULL);
                isempty = TRUE;
                isapoint = TRUE;
            } else if (!isfill && !isempty && isapoint) {
                ::LineTo(hdc, x1+1, y1);
                ::MoveToEx(hdc, x1, y1, NULL);
                isempty = TRUE;
                isapoint = TRUE;
            }
            break;
        }
    }
    env->ReleasePrimitiveArrayCritical(typesarray, types, JNI_ABORT);
    env->ReleasePrimitiveArrayCritical(coordsarray, coords, JNI_ABORT);
    if (ok) {
        if (!isfill && !isempty) {
            // Fix for 4298688 - draw(Line) omits last pixel
            // Windows omits the last pixel of a path when stroking.
            // Fix up the last segment of the previous subpath by
            // adding another segment after it that is only 1 pixel
            // long.  The first pixel of that segment will be drawn,
            // but the second pixel is the one that Windows omits.
            ::LineTo(hdc, x1+1, y1);
        }
        ::EndPath(hdc);
        if (isfill) {
            ::FillPath(hdc);
        } else {
            ::StrokePath(hdc);
        }
    } else {
        ::AbortPath(hdc);
        JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array");
    }
    wsdo->ReleaseDC(env, wsdo, hdc);
}
Esempio n. 17
0
/**
 * Initializes an OpenGL texture object.
 *
 * If the isOpaque parameter is JNI_FALSE, then the texture will have a
 * full alpha channel; otherwise, the texture will be opaque (this can
 * help save VRAM when translucency is not needed).
 *
 * If the GL_ARB_texture_non_power_of_two extension is present (texNonPow2
 * is JNI_TRUE), the actual texture is allowed to have non-power-of-two
 * dimensions, and therefore width==textureWidth and height==textureHeight.
 *
 * Failing that, if the GL_ARB_texture_rectangle extension is present
 * (texRect is JNI_TRUE), the actual texture is allowed to have
 * non-power-of-two dimensions, except that instead of using the usual
 * GL_TEXTURE_2D target, we need to use the GL_TEXTURE_RECTANGLE_ARB target.
 * Note that the GL_REPEAT wrapping mode is not allowed with this target,
 * so if that mode is needed (e.g. as is the case in the TexturePaint code)
 * one should pass JNI_FALSE to avoid using this extension.  Also note that
 * when the texture target is GL_TEXTURE_RECTANGLE_ARB, texture coordinates
 * must be specified in the range [0,width] and [0,height] rather than
 * [0,1] as is the case with the usual GL_TEXTURE_2D target (so take care)!
 *
 * Otherwise, the actual texture must have power-of-two dimensions, and
 * therefore the textureWidth and textureHeight will be the next
 * power-of-two greater than (or equal to) the requested width and height.
 */
static jboolean
OGLSD_InitTextureObject(OGLSDOps *oglsdo,
                        jboolean isOpaque,
                        jboolean texNonPow2, jboolean texRect,
                        jint width, jint height)
{
    GLenum texTarget, texProxyTarget;
    GLint format = isOpaque ? GL_RGB : GL_RGBA;
    GLuint texID;
    GLsizei texWidth, texHeight, realWidth, realHeight;
    GLint texMax;

    J2dTraceLn4(J2D_TRACE_INFO,
                "OGLSD_InitTextureObject: w=%d h=%d opq=%d nonpow2=%d",
                width, height, isOpaque, texNonPow2);

    if (oglsdo == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLSD_InitTextureObject: ops are null");
        return JNI_FALSE;
    }

    if (texNonPow2) {
        // use non-pow2 dimensions with GL_TEXTURE_2D target
        j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax);
        texWidth = (width <= texMax) ? width : 0;
        texHeight = (height <= texMax) ? height : 0;
        texTarget = GL_TEXTURE_2D;
        texProxyTarget = GL_PROXY_TEXTURE_2D;
    } else if (texRect) {
        // use non-pow2 dimensions with GL_TEXTURE_RECTANGLE_ARB target
        j2d_glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texMax);
        texWidth = (width <= texMax) ? width : 0;
        texHeight = (height <= texMax) ? height : 0;
        texTarget = GL_TEXTURE_RECTANGLE_ARB;
        texProxyTarget = GL_PROXY_TEXTURE_RECTANGLE_ARB;
    } else {
        // find the appropriate power-of-two dimensions
        j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax);
        texWidth = OGLSD_NextPowerOfTwo(width, texMax);
        texHeight = OGLSD_NextPowerOfTwo(height, texMax);
        texTarget = GL_TEXTURE_2D;
        texProxyTarget = GL_PROXY_TEXTURE_2D;
    }

    J2dTraceLn3(J2D_TRACE_VERBOSE,
                "  desired texture dimensions: w=%d h=%d max=%d",
                texWidth, texHeight, texMax);

    // if either dimension is 0, we cannot allocate a texture with the
    // requested dimensions
    if ((texWidth == 0) || (texHeight == 0)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLSD_InitTextureObject: texture dimensions too large");
        return JNI_FALSE;
    }

    // now use a proxy to determine whether we can create a texture with
    // the calculated power-of-two dimensions and the given internal format
    j2d_glTexImage2D(texProxyTarget, 0, format,
                     texWidth, texHeight, 0,
                     format, GL_UNSIGNED_BYTE, NULL);
    j2d_glGetTexLevelParameteriv(texProxyTarget, 0,
                                 GL_TEXTURE_WIDTH, &realWidth);
    j2d_glGetTexLevelParameteriv(texProxyTarget, 0,
                                 GL_TEXTURE_HEIGHT, &realHeight);

    // if the requested dimensions and proxy dimensions don't match,
    // we shouldn't attempt to create the texture
    if ((realWidth != texWidth) || (realHeight != texHeight)) {
        J2dRlsTraceLn2(J2D_TRACE_ERROR,
            "OGLSD_InitTextureObject: actual (w=%d h=%d) != requested",
                       realWidth, realHeight);
        return JNI_FALSE;
    }

    // initialize the texture with some dummy data (this allows us to create
    // a texture object once with 2^n dimensions, and then use
    // glTexSubImage2D() to provide further updates)
    j2d_glGenTextures(1, &texID);
    j2d_glBindTexture(texTarget, texID);
    j2d_glTexImage2D(texTarget, 0, format,
                     texWidth, texHeight, 0,
                     format, GL_UNSIGNED_BYTE, NULL);

    oglsdo->isOpaque = isOpaque;
    oglsdo->xOffset = 0;
    oglsdo->yOffset = 0;
    oglsdo->width = width;
    oglsdo->height = height;
    oglsdo->textureID = texID;
    oglsdo->textureWidth = texWidth;
    oglsdo->textureHeight = texHeight;
    oglsdo->textureTarget = texTarget;
    OGLSD_INIT_TEXTURE_FILTER(oglsdo, GL_NEAREST);
    OGLSD_RESET_TEXTURE_WRAP(texTarget);

    J2dTraceLn3(J2D_TRACE_VERBOSE, "  created texture: w=%d h=%d id=%d",
                width, height, texID);

    return JNI_TRUE;
}
Esempio n. 18
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;
}
Esempio n. 19
0
JNIEXPORT jboolean JNICALL
Java_sun_java2d_opengl_WGLSurfaceData_initPbuffer
    (JNIEnv *env, jobject wglsd,
     jlong pData, jlong pConfigInfo,
     jboolean isOpaque,
     jint width, jint height)
{
    int attrKeys[] = {
        WGL_MAX_PBUFFER_WIDTH_ARB,
        WGL_MAX_PBUFFER_HEIGHT_ARB,
    };
    int attrVals[2];
    int pbAttrList[] = { 0 };
    OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
    WGLGraphicsConfigInfo *wglInfo =
        (WGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
    WGLSDOps *wglsdo;
    HWND hwnd;
    HDC hdc, pbufferDC;
    HPBUFFERARB pbuffer;
    int maxWidth, maxHeight;
    int actualWidth, actualHeight;

    J2dTraceLn3(J2D_TRACE_INFO,
                "WGLSurfaceData_initPbuffer: w=%d h=%d opq=%d",
                width, height, isOpaque);

    if (oglsdo == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: ops are null");
        return JNI_FALSE;
    }

    wglsdo = (WGLSDOps *)oglsdo->privOps;
    if (wglsdo == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: wgl ops are null");
        return JNI_FALSE;
    }

    if (wglInfo == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: wgl config info is null");
        return JNI_FALSE;
    }

    // create a scratch window
    hwnd = WGLGC_CreateScratchWindow(wglInfo->screen);
    if (hwnd == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: could not create scratch window");
        return JNI_FALSE;
    }

    // get the HDC for the scratch window
    hdc = GetDC(hwnd);
    if (hdc == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: could not get dc for scratch window");
        DestroyWindow(hwnd);
        return JNI_FALSE;
    }

    // get the maximum allowable pbuffer dimensions
    j2d_wglGetPixelFormatAttribivARB(hdc, wglInfo->pixfmt, 0, 2,
                                     attrKeys, attrVals);
    maxWidth  = attrVals[0];
    maxHeight = attrVals[1];

    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  desired pbuffer dimensions: w=%d h=%d maxw=%d maxh=%d",
                width, height, maxWidth, maxHeight);

    // if either dimension is 0 or larger than the maximum, we cannot
    // allocate a pbuffer with the requested dimensions
    if (width  == 0 || width  > maxWidth ||
        height == 0 || height > maxHeight)
    {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: invalid dimensions");
        ReleaseDC(hwnd, hdc);
        DestroyWindow(hwnd);
        return JNI_FALSE;
    }

    pbuffer = j2d_wglCreatePbufferARB(hdc, wglInfo->pixfmt,
                                      width, height, pbAttrList);

    ReleaseDC(hwnd, hdc);
    DestroyWindow(hwnd);

    if (pbuffer == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: could not create wgl pbuffer");
        return JNI_FALSE;
    }

    // note that we get the DC for the pbuffer at creation time, and then
    // release the DC when the pbuffer is disposed; the WGL_ARB_pbuffer
    // spec is vague about such things, but from past experience we know
    // this approach to be more robust than, for example, doing a
    // Get/ReleasePbufferDC() everytime we make a context current
    pbufferDC = j2d_wglGetPbufferDCARB(pbuffer);
    if (pbufferDC == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: could not get dc for pbuffer");
        j2d_wglDestroyPbufferARB(pbuffer);
        return JNI_FALSE;
    }

    // make sure the actual dimensions match those that we requested
    j2d_wglQueryPbufferARB(pbuffer, WGL_PBUFFER_WIDTH_ARB, &actualWidth);
    j2d_wglQueryPbufferARB(pbuffer, WGL_PBUFFER_HEIGHT_ARB, &actualHeight);

    if (width != actualWidth || height != actualHeight) {
        J2dRlsTraceLn2(J2D_TRACE_ERROR,
            "WGLSurfaceData_initPbuffer: actual (w=%d h=%d) != requested",
                       actualWidth, actualHeight);
        j2d_wglReleasePbufferDCARB(pbuffer, pbufferDC);
        j2d_wglDestroyPbufferARB(pbuffer);
        return JNI_FALSE;
    }

    oglsdo->drawableType = OGLSD_PBUFFER;
    oglsdo->isOpaque = isOpaque;
    oglsdo->width = width;
    oglsdo->height = height;
    wglsdo->pbuffer = pbuffer;
    wglsdo->pbufferDC = pbufferDC;

    OGLSD_SetNativeDimensions(env, oglsdo, width, height);

    return JNI_TRUE;
}
Esempio n. 20
0
/**
 * Makes a context current to the given source and destination
 * surfaces.  If there is a problem making the context current, this method
 * will return NULL; otherwise, returns a pointer to the OGLContext that is
 * associated with the destination surface.
 */
OGLContext *
OGLSD_MakeOGLContextCurrent(JNIEnv *env, OGLSDOps *srcOps, OGLSDOps *dstOps)
{
    WGLSDOps *srcWGLOps = (WGLSDOps *)srcOps->privOps;
    WGLSDOps *dstWGLOps = (WGLSDOps *)dstOps->privOps;
    OGLContext *oglc;
    WGLCtxInfo *ctxinfo;
    HDC srcHDC, dstHDC;
    BOOL success;

    J2dTraceLn(J2D_TRACE_INFO, "OGLSD_MakeOGLContextCurrent");

    J2dTraceLn4(J2D_TRACE_VERBOSE, "  src: %d %p dst: %d %p",
                srcOps->drawableType, srcOps,
                dstOps->drawableType, dstOps);

    oglc = dstWGLOps->configInfo->context;
    if (oglc == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLSD_MakeOGLContextCurrent: context is null");
        return NULL;
    }

    if (dstOps->drawableType == OGLSD_FBOBJECT) {
        OGLContext *currentContext = OGLRenderQueue_GetCurrentContext();

        // first make sure we have a current context (if the context isn't
        // already current to some drawable, we will make it current to
        // its scratch surface)
        if (oglc != currentContext) {
            if (!WGLSD_MakeCurrentToScratch(env, oglc)) {
                return NULL;
            }
        }

        // now bind to the fbobject associated with the destination surface;
        // this means that all rendering will go into the fbobject destination
        // (note that we unbind the currently bound texture first; this is
        // recommended procedure when binding an fbobject)
        j2d_glBindTexture(dstOps->textureTarget, 0);
        j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, dstOps->fbobjectID);

        return oglc;
    }

    ctxinfo = (WGLCtxInfo *)oglc->ctxInfo;

    // get the hdc for the destination surface
    if (dstOps->drawableType == OGLSD_PBUFFER) {
        dstHDC = dstWGLOps->pbufferDC;
    } else {
        dstHDC = GetDC(dstWGLOps->window);
    }

    // get the hdc for the source surface
    if (srcOps->drawableType == OGLSD_PBUFFER) {
        srcHDC = srcWGLOps->pbufferDC;
    } else {
        // the source will always be equal to the destination in this case
        srcHDC = dstHDC;
    }

    // REMIND: in theory we should be able to use wglMakeContextCurrentARB()
    // even when the src/dst surfaces are the same, but this causes problems
    // on ATI's drivers (see 6525997); for now we will only use it when the
    // surfaces are different, otherwise we will use the old
    // wglMakeCurrent() approach...
    if (srcHDC != dstHDC) {
        // use WGL_ARB_make_current_read extension to make context current
        success =
            j2d_wglMakeContextCurrentARB(dstHDC, srcHDC, ctxinfo->context);
    } else {
        // use the old approach for making current to the destination
        success = j2d_wglMakeCurrent(dstHDC, ctxinfo->context);
    }
    if (!success) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLSD_MakeOGLContextCurrent: could not make current");
        if (dstOps->drawableType != OGLSD_PBUFFER) {
            ReleaseDC(dstWGLOps->window, dstHDC);
        }
        return NULL;
    }

    if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
        // the GL_EXT_framebuffer_object extension is present, so we
        // must bind to the default (windowing system provided)
        // framebuffer
        j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    }

    if (dstOps->drawableType != OGLSD_PBUFFER) {
        ReleaseDC(dstWGLOps->window, dstHDC);
    }

    return oglc;
}