Пример #1
0
/**
 * Removes cell info from the glyph's list of cached cells.
 */
void
AccelGlyphCache_RemoveCellInfo(GlyphInfo *glyph, CacheCellInfo *cellInfo)
{
    CacheCellInfo *currCellInfo = glyph->cellInfo;
    CacheCellInfo *prevInfo = NULL;
    // assert (glyph!= NULL && glyph->cellInfo != NULL && cellInfo != NULL)
    J2dTraceLn(J2D_TRACE_INFO, "AccelGlyphCache_RemoveCellInfo");
    do {
        if (currCellInfo == cellInfo) {
            J2dTraceLn2(J2D_TRACE_VERBOSE,
                        "  glyph 0x%x: removing cell 0x%x from glyph's list",
                        glyph, currCellInfo);
            if (prevInfo == NULL) { // it's the head, chop-chop
                glyph->cellInfo = currCellInfo->nextGCI;
            } else {
                prevInfo->nextGCI = currCellInfo->nextGCI;
            }
            currCellInfo->glyphInfo = NULL;
            currCellInfo->nextGCI = NULL;
            return;
        }
        prevInfo = currCellInfo;
        currCellInfo = currCellInfo->nextGCI;
    } while (currCellInfo != NULL);
    J2dTraceLn2(J2D_TRACE_WARNING, "AccelGlyphCache_RemoveCellInfo: "\
                "no cell 0x%x in glyph 0x%x's cell list",
                cellInfo, glyph);
}
Пример #2
0
// static
HRESULT D3DPipelineManager::HandleAdaptersChange(HMONITOR *pHMONITORs, UINT monNum)
{
    HRESULT res = S_OK;
    BOOL bResetD3D = FALSE, bFound;

    D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
    RETURN_STATUS_IF_NULL(pHMONITORs, E_FAIL);
    if (pMgr == NULL) {
        // NULL pMgr is valid when the pipeline is not enabled or if it hasn't
        // been created yet
        return S_OK;
    }
    RETURN_STATUS_IF_NULL(pMgr->pAdapters, E_FAIL);
    RETURN_STATUS_IF_NULL(pMgr->pd3d9, E_FAIL);

    J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::HandleAdaptersChange");

    if (monNum != pMgr->adapterCount) {
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                   "  number of adapters changed (old=%d, new=%d)",
                   pMgr->adapterCount, monNum);
        bResetD3D = TRUE;
    } else {
        for (UINT i = 0; i < pMgr->adapterCount; i++) {
            HMONITOR hMon = pMgr->pd3d9->GetAdapterMonitor(i);
            if (hMon == (HMONITOR)0x0) {
                J2dTraceLn1(J2D_TRACE_VERBOSE, "  adapter %d: removed", i);
                bResetD3D = TRUE;
                break;
            }
            bFound = FALSE;
            for (UINT mon = 0; mon < monNum; mon++) {
                if (pHMONITORs[mon] == hMon) {
                    J2dTraceLn3(J2D_TRACE_VERBOSE,
                            "  adapter %d: found hmnd[%d]=0x%x", i, mon, hMon);
                    bFound = TRUE;
                    break;
                }
            }
            if (!bFound) {
                J2dTraceLn2(J2D_TRACE_VERBOSE,
                            "  adapter %d: could not find hmnd=0x%x "\
                            "in the list of new hmnds", i, hMon);
                bResetD3D = TRUE;
                break;
            }
        }
    }

    if (bResetD3D) {
        J2dTraceLn(J2D_TRACE_VERBOSE, "  adapters changed: resetting d3d");
        pMgr->ReleaseD3D();
        res = pMgr->InitD3D();
    }
    return res;
}
Пример #3
0
/**
 * Fetches the OGLContext associated with the given destination surface,
 * makes the context current for those surfaces, updates the destination
 * viewport, and then returns a pointer to the OGLContext.
 */
OGLContext *
OGLContext_SetSurfaces(JNIEnv *env, jlong pSrc, jlong pDst)
{
    OGLSDOps *srcOps = (OGLSDOps *)jlong_to_ptr(pSrc);
    OGLSDOps *dstOps = (OGLSDOps *)jlong_to_ptr(pDst);
    OGLContext *oglc = NULL;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_SetSurfaces");

    if (srcOps == NULL || dstOps == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLContext_SetSurfaces: ops are null");
        return NULL;
    }

    J2dTraceLn2(J2D_TRACE_VERBOSE, "  srctype=%d dsttype=%d",
                srcOps->drawableType, dstOps->drawableType);

    if (dstOps->drawableType == OGLSD_TEXTURE) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLContext_SetSurfaces: texture cannot be used as destination");
        return NULL;
    }

    if (dstOps->drawableType == OGLSD_UNDEFINED) {
        // initialize the surface as an OGLSD_WINDOW
        if (!OGLSD_InitOGLWindow(env, dstOps)) {
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                          "OGLContext_SetSurfaces: could not init OGL window");
            return NULL;
        }
    }

    // make the context current
    oglc = OGLSD_MakeOGLContextCurrent(env, srcOps, dstOps);
    if (oglc == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLContext_SetSurfaces: could not make context current");
        return NULL;
    }

    // update the viewport
    OGLContext_SetViewport(srcOps, dstOps);

    // perform additional one-time initialization, if necessary
    if (dstOps->needsInit) {
        if (dstOps->isOpaque) {
            // in this case we are treating the destination as opaque, but
            // to do so, first we need to ensure that the alpha channel
            // is filled with fully opaque values (see 6319663)
            OGLContext_InitAlphaChannel();
        }
        dstOps->needsInit = JNI_FALSE;
    }

    return oglc;
}
Пример #4
0
// static
HRESULT
D3DPipelineManager::GDICheckForBadHardware()
{
    DISPLAY_DEVICE dd;
    dd.cb = sizeof(DISPLAY_DEVICE);

    int failedDevices = 0;
    int attachedDevices = 0;
    int i = 0;
    WCHAR *id;
    WCHAR vendorId[5];
    WCHAR deviceId[5];
    DWORD dwDId, dwVId;

    J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GDICheckForBadHardware");

    // i<20 is to guard against buggy drivers
    while (EnumDisplayDevices(NULL, i, &dd, 0) && i < 20) {
        if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
            attachedDevices++;
            id = dd.DeviceID;
            if (wcslen(id) > 21) {
                // get vendor ID
                wcsncpy(vendorId, id+8, 4);
                int args1 = swscanf(vendorId, L"%X", &dwVId);

                // get device ID
                wcsncpy(deviceId, id+17, 4);
                int args2 = swscanf(deviceId, L"%X", &dwDId);

                if (args1 == 1 && args2 == 1) {
                    J2dTraceLn2(J2D_TRACE_VERBOSE,
                                "  device: vendorID=0x%04x, deviceId=0x%04x",
                                dwVId, dwDId);
                    // since we don't have a driver version here we will
                    // just ask to ignore the version for now; bad hw
                    // entries with specific drivers information will be
                    // processed later when d3d is initialized and we can
                    // obtain a driver version
                    if (FAILED(CheckForBadHardware(dwVId, dwDId, MAX_VERSION))){
                        failedDevices++;
                    }
                }
            }
        }

        i++;
    }

    if (failedDevices == attachedDevices) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "D3DPPLM::GDICheckForBadHardware: no suitable devices found");
        return E_FAIL;
    }

    return S_OK;
}
Пример #5
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);
}
Пример #6
0
/**
 * Initializes a framebuffer object, using the given width and height as
 * a guide.  See OGLSD_InitTextureObject() and OGLSD_InitFBObject()
 * for more information.
 */
JNIEXPORT jboolean JNICALL
Java_sun_java2d_opengl_OGLSurfaceData_initFBObject
    (JNIEnv *env, jobject oglsd,
     jlong pData, jboolean isOpaque,
     jboolean texNonPow2, jboolean texRect,
     jint width, jint height)
{
    OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
    GLuint fbobjectID, depthID;

    J2dTraceLn2(J2D_TRACE_INFO,
                "OGLSurfaceData_initFBObject: w=%d h=%d",
                width, height);

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

    // initialize color texture object
    if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect,
                                 width, height))
    {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLSurfaceData_initFBObject: could not init texture object");
        return JNI_FALSE;
    }

    // initialize framebuffer object using color texture created above
    if (!OGLSD_InitFBObject(&fbobjectID, &depthID,
                            oglsdo->textureID, oglsdo->textureTarget,
                            oglsdo->textureWidth, oglsdo->textureHeight))
    {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLSurfaceData_initFBObject: could not init fbobject");
        j2d_glDeleteTextures(1, &oglsdo->textureID);
        return JNI_FALSE;
    }

    oglsdo->drawableType = OGLSD_FBOBJECT;
    // other fields (e.g. width, height) are set in OGLSD_InitTextureObject()
    oglsdo->fbobjectID = fbobjectID;
    oglsdo->depthID = depthID;

    OGLSD_SetNativeDimensions(env, oglsdo,
                              oglsdo->textureWidth, oglsdo->textureHeight);

    // framebuffer objects differ from other OpenGL surfaces in that the
    // value passed to glRead/DrawBuffer() must be GL_COLOR_ATTACHMENTn_EXT,
    // rather than GL_FRONT (or GL_BACK)
    oglsdo->activeBuffer = GL_COLOR_ATTACHMENT0_EXT;

    return JNI_TRUE;
}
Пример #7
0
/*
 * Class:     sun_java2d_windows_GDIRenderer
 * Method:    doFillArc
 * Signature: (Lsun/java2d/windows/GDIWindowSurfaceData;Lsun/java2d/pipe/Region;Ljava/awt/Composite;IIIIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIRenderer_doFillArc
    (JNIEnv *env, jobject wr,
     jobject sData,
     jobject clip, jobject comp, jint color,
     jint x, jint y, jint w, jint h,
     jint angleStart, jint angleExtent)
{
    J2dTraceLn(J2D_TRACE_INFO, "GDIRenderer_doFillArc");
    J2dTraceLn5(J2D_TRACE_VERBOSE,
                "  color=0x%x x=%-4d y=%-4d w=%-4d h=%-4d",
                color, x, y, w, h);
    J2dTraceLn2(J2D_TRACE_VERBOSE,
                "  angleStart=%-4d angleExtent=%-4d",
                angleStart, angleExtent);
    if (w <= 0 || h <= 0 || angleExtent == 0) {
        return;
    }
    if (angleExtent >= 360 || angleExtent <= -360) {
        // Fix related to 4411814 - small ovals (and arcs) do not draw
        // If the arc is a full circle, let the Oval method handle it
        // since that method can deal with degenerate sizes better.
        Java_sun_java2d_windows_GDIRenderer_doFillOval(env, wr,
                                                       sData, clip,
                                                       comp, color,
                                                       x, y, w, h);
        return;
    }

    GDIWinSDOps *wsdo = GDIWindowSurfaceData_GetOps(env, sData);
    if (wsdo == NULL) {
        return;
    }
    long sx, sy, ex, ey;
    int angleEnd;
    if (angleExtent < 0) {
        angleEnd = angleStart;
        angleStart += angleExtent;
    } else {
        angleEnd = angleStart + angleExtent;
    }
    AngleToCoord(angleStart, w, h, &sx, &sy);
    sx += x + w/2;
    sy += y + h/2;
    AngleToCoord(angleEnd, w, h, &ex, &ey);
    ex += x + w/2;
    ey += y + h/2;
    HDC hdc = wsdo->GetDC(env, wsdo, BRUSHONLY, NULL, clip, comp, color);
    if (hdc == NULL) {
        return;
    }
    ::Pie(hdc, x, y, x+w+1, y+h+1, sx, sy, ex, ey);
    wsdo->ReleaseDC(env, wsdo, hdc);
}
Пример #8
0
HWND D3DPipelineManager::SetFSFocusWindow(UINT adapterOrdinal, HWND hWnd)
{
    J2dTraceLn2(J2D_TRACE_INFO,"D3DPPLM::SetFSFocusWindow hwnd=0x%x adapter=%d",
                hWnd, adapterOrdinal);

    HWND prev = pAdapters[adapterOrdinal].fsFocusWindow;
    pAdapters[adapterOrdinal].fsFocusWindow = hWnd;
    if (currentFSFocusAdapter < 0) {
        J2dTraceLn(J2D_TRACE_VERBOSE, "  first full-screen window");
        // first fs window
        currentFSFocusAdapter = adapterOrdinal;
        // REMIND: we might want to reset the rest of the context here as well
        // like we do when the an adapter exits fs mode; currently they will
        // be reset sometime later
    } else {
        // there's already a fs window
        if (currentFSFocusAdapter == adapterOrdinal) {
            // it's current fs window => we're exiting fs mode on this adapter;
            // look for a new fs focus window
            if (hWnd == 0) {
                UINT i;
                currentFSFocusAdapter = -1;
                for (i = 0; i < adapterCount; i++) {
                    if (pAdapters[i].fsFocusWindow != 0) {
                        J2dTraceLn1(J2D_TRACE_VERBOSE,
                                    "  adapter %d is still in fs mode", i);
                        currentFSFocusAdapter = i;
                        break;
                    }
                }
                // we have to reset all devices any time current focus device
                // exits fs mode, and also to prevent some of them being left in
                // a lost state when the last device exits fs - when non-last
                // adapters exit fs mode they would not be able to create the
                // device and will be put in a lost state forever
                HRESULT res;
                J2dTraceLn(J2D_TRACE_VERBOSE,
                           "  adapter exited full-screen, reset all adapters");
                for (i = 0; i < adapterCount; i++) {
                    if (pAdapters[i].pd3dContext != NULL) {
                        res = pAdapters[i].pd3dContext->ResetContext();
                        D3DRQ_MarkLostIfNeeded(res,
                            D3DRQ_GetCurrentDestination());
                    }
                }
            } else {
                J2dTraceLn1(J2D_TRACE_WARNING,
                            "D3DPM::SetFSFocusWindow: setting the fs "\
                            "window again for adapter %d", adapterOrdinal);
            }
        }
    }
    return prev;
}
Пример #9
0
void
D3DResource::SetSDOps(D3DSDOps *pOps)
{
    if (pOps != NULL && this->pOps != NULL) {
        // something's wrong, we're overwriting
        // a non-null field (setting it to null is allowed)
        J2dTraceLn2(J2D_TRACE_WARNING,
                    "D3DResource::SetSDOps: overwriting "\
                    "this->pOps=0x%x with pOps=0x%x", this->pOps, pOps);
    }
    this->pOps = pOps;
}
Пример #10
0
HWND D3DPipelineManager::CreateDefaultFocusWindow()
{
    UINT adapterOrdinal = D3DADAPTER_DEFAULT;

    J2dTraceLn1(J2D_TRACE_INFO,
                "D3DPPLM::CreateDefaultFocusWindow: adapter=%d",
                adapterOrdinal);

    if (defaultFocusWindow != 0) {
        J2dRlsTraceLn(J2D_TRACE_WARNING,
                      "D3DPPLM::CreateDefaultFocusWindow: "\
                      "existing default focus window!");
        return defaultFocusWindow;
    }

    WNDCLASS wc;
    ZeroMemory(&wc, sizeof(WNDCLASS));
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpfnWndProc = DefWindowProc;
    wc.lpszClassName = L"D3DFocusWindow";
    if (RegisterClass(&wc) == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "D3DPPLM::CreateDefaultFocusWindow: "\
                      "error registering window class");
        return 0;
    }

    MONITORINFO mi;
    ZeroMemory(&mi, sizeof(MONITORINFO));
    mi.cbSize = sizeof(MONITORINFO);
    HMONITOR hMon = pd3d9->GetAdapterMonitor(adapterOrdinal);
    if (hMon == 0 || !GetMonitorInfo(hMon, (LPMONITORINFO)&mi)) {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
            "D3DPPLM::CreateDefaultFocusWindow: "\
            "error getting monitor info for adapter=%d", adapterOrdinal);
        return 0;
    }

    HWND hWnd = CreateWindow(L"D3DFocusWindow", L"D3DFocusWindow", 0,
        mi.rcMonitor.left, mi.rcMonitor.top, 1, 1,
        NULL, NULL, GetModuleHandle(NULL), NULL);
    if (hWnd == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "D3DPPLM::CreateDefaultFocusWindow: CreateWindow failed");
    } else {
        J2dTraceLn2(J2D_TRACE_INFO,
            "  Created default focus window %x for adapter %d",
            hWnd, adapterOrdinal);
        defaultFocusWindow = hWnd;
    }
    return hWnd;
}
Пример #11
0
/**
 * Add cell info to the head of the glyph's list of cached cells.
 */
void
AccelGlyphCache_AddCellInfo(GlyphInfo *glyph, CacheCellInfo *cellInfo)
{
    // assert (glyph != NULL && cellInfo != NULL)
    J2dTraceLn(J2D_TRACE_INFO, "AccelGlyphCache_AddCellInfo");
    J2dTraceLn2(J2D_TRACE_VERBOSE, "  glyph 0x%x: adding cell 0x%x to the list",
                glyph, cellInfo);

    cellInfo->glyphInfo = glyph;
    cellInfo->nextGCI = glyph->cellInfo;
    glyph->cellInfo = cellInfo;
    glyph->managed = MANAGED_GLYPH;
}
Пример #12
0
/**
 * Retrieve a pointer to an item in the array and register a
 * reference to the array.  This increases the refCount of the
 * instance, used to track when the array can be deleted.
 *
 * This method must be called while holding a reference to the instance.
 *
 * If adjust parameter is true (default), adjust the index into the 
 * devices array so that it falls within the current devices array. 
 * This is needed because the devices array can be changed at any 
 * time, and the index may be from the old array. But in some 
 * cases we prefer to know that the index is incorrect.
 *
 */
AwtWin32GraphicsDevice *Devices::GetDeviceReference(int index,
                                                    BOOL adjust)
{
    J2dTraceLn2(J2D_TRACE_INFO, 
                "Devices::GetDeviceReference index=%d adjust?=%d",
                index, adjust);

    AwtWin32GraphicsDevice * ret = GetDevice(index, adjust);
    if (ret != NULL) {
        AddReference();
    }
    return ret;
}
Пример #13
0
/*
 * Class:     sun_java2d_windows_GDIRenderer
 * Method:    doDrawArc
 * Signature: (Lsun/java2d/windows/GDIWindowSurfaceData;Lsun/java2d/pipe/Region;Ljava/awt/Composite;IIIIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIRenderer_doDrawArc
    (JNIEnv *env, jobject wr,
     jobject sData,
     jobject clip, jobject comp, jint color,
     jint x, jint y, jint w, jint h,
     jint angleStart, jint angleExtent)
{
    J2dTraceLn(J2D_TRACE_INFO, "GDIRenderer_doDrawArc");
    J2dTraceLn5(J2D_TRACE_VERBOSE,
                "  color=0x%x x=%-4d y=%-4d w=%-4d h=%-4d",
                color, x, y, w, h);
    J2dTraceLn2(J2D_TRACE_VERBOSE,
                "  angleStart=%-4d angleExtent=%-4d",
                angleStart, angleExtent);
    if (w < 0 || h < 0 || angleExtent == 0) {
        return;
    }

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

    long sx, sy, ex, ey;
    if (angleExtent >= 360 || angleExtent <= -360) {
        sx = ex = x + w;
        sy = ey = y + h/2;
    } else {
        int angleEnd;
        if (angleExtent < 0) {
            angleEnd = angleStart;
            angleStart += angleExtent;
        } else {
            angleEnd = angleStart + angleExtent;
        }
        AngleToCoord(angleStart, w, h, &sx, &sy);
        sx += x + w/2;
        sy += y + h/2;
        AngleToCoord(angleEnd, w, h, &ex, &ey);
        ex += x + w/2;
        ey += y + h/2;
    }
    HDC hdc = wsdo->GetDC(env, wsdo, PEN, NULL, clip, comp, color);
    if (hdc == NULL) {
        return;
    }
    ::Arc(hdc, x, y, x+w+1, y+h+1, sx, sy, ex, ey);
    wsdo->ReleaseDC(env, wsdo, hdc);
}
Пример #14
0
HRESULT D3DVertexCacher::EnsureCapacity(D3DPRIMITIVETYPE newPType, UINT vNum)
{
    HRESULT res = D3D_OK;
    if (vNum > MAX_BATCH_SIZE) {
        // REMIND: need to define our own errors
        return D3DERR_NOTAVAILABLE;
    }
    if ((firstUnusedVertex + vNum) > MAX_BATCH_SIZE) {
        // if we can't fit new vertices in the vertex buffer,
        // render whatever we have in the buffer and start
        // from the beginning of the vertex buffer
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "D3DVC::EnsureCapacity exceeded capacity. "\
                    "current v: %d, requested vertices: %d\n",
                    firstUnusedVertex, vNum);
        if (FAILED(res = Render(RESET_ACTION))) {
            return res;
        }
    }

    J2dTraceLn5(J2D_TRACE_VERBOSE,
                "D3DVC::EnsureCapacity current batch: %d "\
                " batch.type=%d newType=%d vNum=%d firstUnusedV=%d",
                currentBatch, batches[currentBatch].pType, newPType, vNum,
                firstUnusedVertex);
    // there should not be multiple linestrips in a batch,
    // or they will be counted as a single line strip
    if (batches[currentBatch].pType != newPType ||
        batches[currentBatch].pType == D3DPT_LINESTRIP)
    {
        // if this is a first unused batch, use it
        if (firstUnusedVertex == firstPendingVertex) {
            // record the first batch and vertex scheduled for rendering
            firstPendingBatch = currentBatch;
            firstPendingVertex = firstUnusedVertex;
        } else {
            // otherwise go to the next batch
            currentBatch++;
        }
        batches[currentBatch].pType = newPType;
        batches[currentBatch].pNum = 0;
    }
    // firstUnusedVertex is updated when new vertices are added
    // to the vertices array

    return res;
}
Пример #15
0
/**
 * This function initializes a native window surface and caches the window
 * bounds in the given OGLSDOps.  Returns JNI_TRUE if the operation was
 * successful; JNI_FALSE otherwise.
 */
jboolean
OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo)
{
    GLXSDOps *glxsdo;
    Window window;
    XWindowAttributes attr;

    J2dTraceLn(J2D_TRACE_INFO, "OGLSD_InitOGLWindow");

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

    glxsdo = (GLXSDOps *)oglsdo->privOps;
    if (glxsdo == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLSD_InitOGLWindow: glx ops are null");
        return JNI_FALSE;
    }

    window = glxsdo->window;
    if (window == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLSD_InitOGLWindow: window is invalid");
        return JNI_FALSE;
    }

    XGetWindowAttributes(awt_display, window, &attr);
    oglsdo->width = attr.width;
    oglsdo->height = attr.height;

    oglsdo->drawableType = OGLSD_WINDOW;
    oglsdo->isOpaque = JNI_TRUE;
    oglsdo->xOffset = 0;
    oglsdo->yOffset = 0;
    glxsdo->drawable = window;
    glxsdo->xdrawable = window;

    J2dTraceLn2(J2D_TRACE_VERBOSE, "  created window: w=%d h=%d",
                oglsdo->width, oglsdo->height);

    return JNI_TRUE;
}
Пример #16
0
// REMIND: this method is currently unused; consider removing it later...
HRESULT D3DResourceManager::CreateOSPSurface(UINT width, UINT height,
                                         D3DFORMAT fmt,
                                         D3DResource** ppSurfaceResource/*out*/)
{
    HRESULT res;
    IDirect3DDevice9 *pd3dDevice;

    J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateOSPSurface");
    J2dTraceLn2(J2D_TRACE_VERBOSE, "  w=%d h=%d", width, height);

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

    // since the off-screen plain surface is intended to be used with
    // the UpdateSurface() method, it is essential that it be created
    // in the same format as the destination and allocated in the
    // SYSTEMMEM pool (otherwise UpdateSurface() will fail)
    D3DFORMAT format;
    if (fmt == D3DFMT_UNKNOWN) {
        format = pCtx->GetPresentationParams()->BackBufferFormat;
    } else {
        format = fmt;
    }
    D3DPOOL pool = D3DPOOL_SYSTEMMEM;
    IDirect3DSurface9 *pSurface = NULL;

    res = pd3dDevice->CreateOffscreenPlainSurface(width, height,
                                                  format, pool,
                                                  &pSurface, NULL);
    if (SUCCEEDED(res)) {
        J2dTraceLn1(J2D_TRACE_VERBOSE, "  created OSP Surface: 0x%x ",pSurface);
        *ppSurfaceResource = new D3DResource((IDirect3DResource9*)pSurface);
        res = AddResource(*ppSurfaceResource);
    } else {
        DebugPrintD3DError(res, "D3DRM::CreateOSPSurface failed");
        ppSurfaceResource = NULL;
    }
    return res;
}
Пример #17
0
/**
 * Returns a reference to a device with the passed index.
 *
 * This method does not increase the ref count of the Devices instance.
 *
 * This method must be called while holding a reference to the instance.
 */
AwtWin32GraphicsDevice *Devices::GetDevice(int index, BOOL adjust)
{
    J2dTraceLn2(J2D_TRACE_INFO, 
                "Devices::GetDevice index=%d adjust?=%d", 
                index, adjust);
    if (index < 0 || index >= numDevices) {
        if (!adjust) {
            J2dTraceLn1(J2D_TRACE_WARNING, 
                        "Devices::GetDevice: "\
                        "incorrect index %d, returning NULL.", index);
            return NULL;
        }
        J2dTraceLn1(J2D_TRACE_WARNING, 
                    "Devices::GetDevice: "\
                    "adjusted index %d to 0.", index);
        index = 0;
    }
    return devices[index];
}
Пример #18
0
/**
 * Initializes an OpenGL texture, using the given width and height as
 * a guide.  See OGLSD_InitTextureObject() for more information.
 */
JNIEXPORT jboolean JNICALL
Java_sun_java2d_opengl_OGLSurfaceData_initTexture
    (JNIEnv *env, jobject oglsd,
     jlong pData, jboolean isOpaque,
     jboolean texNonPow2, jboolean texRect,
     jint width, jint height)
{
    OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);

    J2dTraceLn2(J2D_TRACE_INFO, "OGLSurfaceData_initTexture: w=%d h=%d",
                width, height);

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

    /*
     * We only use the GL_ARB_texture_rectangle extension if it is available
     * and the requested bounds are not pow2 (it is probably faster to use
     * GL_TEXTURE_2D for pow2 textures, and besides, our TexturePaint
     * code relies on GL_REPEAT, which is not allowed for
     * GL_TEXTURE_RECTANGLE_ARB targets).
     */
    texRect = texRect && !OGLSD_IsPowerOfTwo(width, height);

    if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect,
                                 width, height))
    {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLSurfaceData_initTexture: could not init texture object");
        return JNI_FALSE;
    }

    OGLSD_SetNativeDimensions(env, oglsdo,
                              oglsdo->textureWidth, oglsdo->textureHeight);

    oglsdo->drawableType = OGLSD_TEXTURE;
    // other fields (e.g. width, height) are set in OGLSD_InitTextureObject()

    return JNI_TRUE;
}
Пример #19
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);
            }
        }
    }
}
Пример #20
0
/**
 * Returns cell info associated with particular cache from the glyph's list of
 * cached cells.
 */
CacheCellInfo *
AccelGlyphCache_GetCellInfoForCache(GlyphInfo *glyph, GlyphCacheInfo *cache)
{
    // assert (glyph != NULL && cache != NULL)
    J2dTraceLn(J2D_TRACE_VERBOSE2, "AccelGlyphCache_GetCellInfoForCache");

    if (glyph->cellInfo != NULL) {
        CacheCellInfo *cellInfo = glyph->cellInfo;
        do {
            if (cellInfo->cacheInfo == cache) {
                J2dTraceLn3(J2D_TRACE_VERBOSE2,
                            "  glyph 0x%x: found cell 0x%x for cache 0x%x",
                            glyph, cellInfo, cache);
                return cellInfo;
            }
            cellInfo = cellInfo->nextGCI;
        } while (cellInfo != NULL);
    }
    J2dTraceLn2(J2D_TRACE_VERBOSE2, "  glyph 0x%x: no cell for cache 0x%x",
                glyph, cache);
    return NULL;
}
Пример #21
0
/**
 * Initializes the OpenGL blending state.  XOR mode is disabled and the
 * appropriate blend functions are setup based on the AlphaComposite rule
 * constant.
 */
void
OGLContext_SetAlphaComposite(OGLContext *oglc,
                             jint rule, jfloat extraAlpha, jint flags)
{
    J2dTraceLn1(J2D_TRACE_INFO,
                "OGLContext_SetAlphaComposite: flags=%d", flags);

    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    // disable XOR mode
    if (oglc->compState == sun_java2d_SunGraphics2D_COMP_XOR) {
        j2d_glDisable(GL_COLOR_LOGIC_OP);
        j2d_glDisable(GL_ALPHA_TEST);
    }

    // we can safely disable blending when:
    //   - comp is SrcNoEa or SrcOverNoEa, and
    //   - the source is opaque
    // (turning off blending can have a large positive impact on
    // performance)
    if ((rule == RULE_Src || rule == RULE_SrcOver) &&
            (extraAlpha == 1.0f) &&
            (flags & OGLC_SRC_IS_OPAQUE))
    {
        J2dTraceLn1(J2D_TRACE_VERBOSE,
                    "  disabling alpha comp: rule=%d ea=1.0 src=opq", rule);
        j2d_glDisable(GL_BLEND);
    } else {
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "  enabling alpha comp: rule=%d ea=%f", rule, extraAlpha);
        j2d_glEnable(GL_BLEND);
        j2d_glBlendFunc(StdBlendRules[rule].src, StdBlendRules[rule].dst);
    }

    // update state
    oglc->compState = sun_java2d_SunGraphics2D_COMP_ALPHA;
    oglc->extraAlpha = extraAlpha;
}
Пример #22
0
/*
 * Class:     sun_java2d_windows_GDIRenderer
 * Method:    doDrawRoundRect
 * Signature: (Lsun/java2d/windows/GDIWindowSurfaceData;Lsun/java2d/pipe/Region;Ljava/awt/Composite;IIIIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIRenderer_doDrawRoundRect
    (JNIEnv *env, jobject wr,
     jobject sData,
     jobject clip, jobject comp, jint color,
     jint x, jint y, jint w, jint h, jint arcW, jint arcH)
{
    J2dTraceLn(J2D_TRACE_INFO, "GDIRenderer_doDrawRoundRect");
    J2dTraceLn5(J2D_TRACE_VERBOSE,
                "  color=0x%x x=%-4d y=%-4d w=%-4d h=%-4d",
                color, x, y, w, h);
    J2dTraceLn2(J2D_TRACE_VERBOSE, "  arcW=%-4d arcH=%-4d",
                arcW, arcH);
    if (w < 2 || h < 2 || arcW <= 0 || arcH <= 0) {
        // Fix for 4524760 - drawRoundRect0 test case fails on Windows 98
        // Thin round rects degenerate into regular rectangles
        // because there is no room for the arc sections.  Also
        // if there is no arc dimension then the roundrect must
        // be a simple rectangle.  Defer to the DrawRect function
        // which handles degenerate sizes better.
        Java_sun_java2d_windows_GDIRenderer_doDrawRect(env, wr,
                                                       sData, clip,
                                                       comp, color,
                                                       x, y, w, h);
        return;
    }

    GDIWinSDOps *wsdo = GDIWindowSurfaceData_GetOps(env, sData);
    if (wsdo == NULL) {
        return;
    }
    HDC hdc = wsdo->GetDC(env, wsdo, PENONLY, NULL, clip, comp, color);
    if (hdc == NULL) {
        return;
    }
    ::RoundRect(hdc, x, y, x+w+1, y+h+1, arcW, arcH);
    wsdo->ReleaseDC(env, wsdo, hdc);
}
Пример #23
0
/*
 * Class:     sun_java2d_windows_GDIRenderer
 * Method:    doFillRoundRect
 * Signature: (Lsun/java2d/windows/GDIWindowSurfaceData;Lsun/java2d/pipe/Region;Ljava/awt/Composite;IIIIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIRenderer_doFillRoundRect
    (JNIEnv *env, jobject wr,
     jobject sData,
     jobject clip, jobject comp, jint color,
     jint x, jint y, jint w, jint h, jint arcW, jint arcH)
{
    J2dTraceLn(J2D_TRACE_INFO, "GDIRenderer_doFillRoundRect");
    J2dTraceLn5(J2D_TRACE_VERBOSE,
                "  color=0x%x x=%-4d y=%-4d w=%-4d h=%-4d",
                color, x, y, w, h);
    J2dTraceLn2(J2D_TRACE_VERBOSE, "  arcW=%-4d arcH=%-4d",
                arcW, arcH);
    if (w < 2 || h < 2 || arcW <= 0 || arcH <= 0) {
        // Fix related to 4524760 - drawRoundRect0 fails on Windows 98
        // Thin round rects have no room for curvature.  Also, if
        // the curvature is empty then the primitive has degenerated
        // into a simple rectangle.  Defer to the FillRect method
        // which deals with degenerate sizes better.
        Java_sun_java2d_windows_GDIRenderer_doFillRect(env, wr,
                                                       sData, clip,
                                                       comp, color,
                                                       x, y, w, h);
        return;
    }

    GDIWinSDOps *wsdo = GDIWindowSurfaceData_GetOps(env, sData);
    if (wsdo == NULL) {
        return;
    }
    HDC hdc = wsdo->GetDC(env, wsdo, BRUSHONLY, NULL, clip, comp, color);
    if (hdc == NULL) {
        return;
    }
    ::RoundRect(hdc, x, y, x+w+1, y+h+1, arcW, arcH);
    wsdo->ReleaseDC(env, wsdo, hdc);
}
/**
 * This function initializes a native window surface and caches the window
 * bounds in the given OGLSDOps.  Returns JNI_TRUE if the operation was
 * successful; JNI_FALSE otherwise.
 */
jboolean
OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo)
{
    GLXSDOps *glxsdo;
    Window window;
#ifdef XAWT
    XWindowAttributes attr;
#else
    Widget widget;
#endif

    J2dTraceLn(J2D_TRACE_INFO, "OGLSD_InitOGLWindow");

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

    glxsdo = (GLXSDOps *)oglsdo->privOps;
    if (glxsdo == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLSD_InitOGLWindow: glx ops are null");
        return JNI_FALSE;
    }

#ifdef XAWT
    window = glxsdo->window;
    if (window == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLSD_InitOGLWindow: window is invalid");
        return JNI_FALSE;
    }

    XGetWindowAttributes(awt_display, window, &attr);
    oglsdo->width = attr.width;
    oglsdo->height = attr.height;
#else
    widget = glxsdo->widget;
    if (widget == NULL) {
        J2dTraceLn(J2D_TRACE_WARNING, "OGLSD_InitOGLWindow: widget is null");
    }

    if (!XtIsRealized(widget)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "OGLSD_InitOGLWindow: widget is unrealized");
        return JNI_FALSE;
    }

    window = XtWindow(widget);
    oglsdo->width = widget->core.width;
    oglsdo->height = widget->core.height;
#endif

    oglsdo->drawableType = OGLSD_WINDOW;
    oglsdo->isOpaque = JNI_TRUE;
    oglsdo->xOffset = 0;
    oglsdo->yOffset = 0;
    glxsdo->drawable = window;
    glxsdo->xdrawable = window;

    J2dTraceLn2(J2D_TRACE_VERBOSE, "  created window: w=%d h=%d",
                oglsdo->width, oglsdo->height);

    return JNI_TRUE;
}
Пример #25
0
// static
BOOL Devices::UpdateInstance(JNIEnv *env)
{
    J2dTraceLn(J2D_TRACE_INFO, "Devices::UpdateInstance");

    int numScreens = ::CountMonitors();
    MHND *monHds = (MHND *)safe_Malloc(numScreens * sizeof(MHND));
    if (numScreens != ::CollectMonitors(monHds, numScreens)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR, 
                      "Devices::UpdateInstance: Failed to get all "\
                      "monitor handles.");
        free(monHds);
        return FALSE;
    }

    Devices *newDevices = new Devices(numScreens);
    // This way we know that the array will not be disposed of
    // at least until we replaced it with a new one.
    newDevices->AddReference();

    // Create all devices first, then initialize them.  This allows
    // correct configuration of devices after contruction of the
    // primary device (which may not be device 0).
    AwtWin32GraphicsDevice** rawDevices = newDevices->GetRawArray();
    int i;
    for (i = 0; i < numScreens; ++i) {
        J2dTraceLn2(J2D_TRACE_VERBOSE, "  hmon[%d]=0x%x", i, monHds[i]);
        rawDevices[i] = new AwtWin32GraphicsDevice(i, monHds[i], newDevices);
    }
    for (i = 0; i < numScreens; ++i) {
        rawDevices[i]->Initialize();
    }
    {
        CriticalSection::Lock l(arrayLock);

        // install the new devices array
        Devices *oldDevices = theInstance;
        theInstance = newDevices;

        if (oldDevices) {
            // Invalidate the devices with indexes out of the new set of
            // devices. This doesn't cover all cases when the device
            // might should be invalidated (like if it's not the last device
            // that was removed), but it will have to do for now.
            int oldNumScreens = oldDevices->GetNumDevices();
            int newNumScreens = theInstance->GetNumDevices();
            J2dTraceLn(J2D_TRACE_VERBOSE, "  Invalidating removed devices");
            for (int i = newNumScreens; i < oldNumScreens; i++) {
                // removed device, needs to be invalidated
                J2dTraceLn1(J2D_TRACE_WARNING, 
                            "Devices::UpdateInstance: device removed: %d", i);
                oldDevices->GetDevice(i)->Invalidate(env);
            }
            // Now that we have a new array in place, remove this (possibly the
            // last) reference to the old instance.
            oldDevices->Release();
        }
        D3DPipelineManager::HandleAdaptersChange((HMONITOR*)monHds,
                                                 theInstance->GetNumDevices());
    }
    free(monHds);

    return TRUE;
}
/**
 * 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);
        }
Пример #27
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;
}
Пример #28
0
JNIEXPORT jint JNICALL
Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans
    (JNIEnv *env, jobject pipe,
     jobject rq, jlong buf,
     jint bpos, jint limit,
     jobject si, jlong pIterator,
     jint transx, jint transy)
{
    SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *)jlong_to_ptr(pIterator);
    void *srData;
    jint spanbox[4];
    jint spanCount = 0;
    jint remainingBytes, remainingSpans;
    unsigned char *bbuf;
    jint *ibuf;
    jint ipos;

    J2dTraceLn2(J2D_TRACE_INFO,
                "BufferedRenderPipe_fillSpans: bpos=%d limit=%d",
                bpos, limit);

    if (JNU_IsNull(env, rq)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "BufferedRenderPipe_fillSpans: rq is null");
        return bpos;
    }

    if (JNU_IsNull(env, si)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "BufferedRenderPipe_fillSpans: span iterator is null");
        return bpos;
    }

    if (pFuncs == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "BufferedRenderPipe_fillSpans: native iterator not supplied");
        return bpos;
    }

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

    // adjust the int pointer to the current buffer position
    ibuf = (jint *)(bbuf + bpos);

    // start new operation
    ibuf[0] = sun_java2d_pipe_BufferedOpCodes_FILL_SPANS;
    ibuf[1] = 0; // placeholder for the span count

    // skip the opcode and span count
    ipos = INTS_PER_HEADER;
    bpos += BYTES_PER_HEADER; // skip the opcode and span count

    remainingBytes = limit - bpos;
    remainingSpans = remainingBytes / BYTES_PER_SPAN;

    srData = (*pFuncs->open)(env, si);
    while ((*pFuncs->nextSpan)(srData, spanbox)) {
        if (remainingSpans == 0) {
            // fill in span count
            ibuf[1] = spanCount;

            // flush the queue
            JNU_CallMethodByName(env, NULL, rq, "flushNow", "(I)V", bpos);

            // now start a new operation
            ibuf = (jint *)bbuf;
            ibuf[0] = sun_java2d_pipe_BufferedOpCodes_FILL_SPANS;
            ibuf[1] = 0; // placeholder for the span count

            // skip the opcode and span count
            ipos = INTS_PER_HEADER;
            bpos = BYTES_PER_HEADER;

            // calculate new limits
            remainingBytes = limit - bpos;
            remainingSpans = remainingBytes / BYTES_PER_SPAN;
            spanCount = 0;
        }

        // enqueue span
        ibuf[ipos++] = spanbox[0] + transx; // x1
        ibuf[ipos++] = spanbox[1] + transy; // y1
        ibuf[ipos++] = spanbox[2] + transx; // x2
        ibuf[ipos++] = spanbox[3] + transy; // y2

        // update positions
        bpos += BYTES_PER_SPAN;
        spanCount++;
        remainingSpans--;
    }
    (*pFuncs->close)(env, srData);

    // fill in span count
    ibuf[1] = spanCount;

    // return the current byte position
    return bpos;
}
Пример #29
0
HRESULT D3DVertexCacher::Render(int actionType)
{
    J2DLVERTEX *lpVert;
    HRESULT res;
    DWORD dwLockFlags;
    UINT pendingVertices = firstUnusedVertex - firstPendingVertex;

    // nothing to render
    if (pendingVertices == 0) {
        if (actionType == RESET_ACTION) {
            firstPendingBatch = 0;
            firstPendingVertex = 0;
            firstUnusedVertex = 0;
            currentBatch = 0;
        }
        return D3D_OK;
    }

    if (firstPendingVertex == 0) {
        // no data in the buffer yet, we don't care about
        // vertex buffer's contents
        dwLockFlags = D3DLOCK_DISCARD;
    } else {
        // append to the existing data in the vertex buffer
        dwLockFlags = D3DLOCK_NOOVERWRITE;
    }

    if (SUCCEEDED(res =
        lpD3DVertexBuffer->Lock((UINT)firstPendingVertex*sizeof(J2DLVERTEX),
                                (UINT)pendingVertices*sizeof(J2DLVERTEX),
                                (void**)&lpVert, dwLockFlags)))
    {
        // copy only new vertices
        memcpy((void *)lpVert,
               (void *)(vertices + firstPendingVertex),
               pendingVertices * sizeof(J2DLVERTEX));
        res = lpD3DVertexBuffer->Unlock();
        UINT currentVertex = firstPendingVertex;
        UINT batchSize;
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "D3DVC::Render Starting flushing of %d vertices "\
                    "in %d batches",
                    pendingVertices,
                    (currentBatch - firstPendingBatch + 1));


        for (UINT b = firstPendingBatch; b <= currentBatch; b++) {
            D3DPRIMITIVETYPE pType = batches[b].pType;
            UINT primCount = batches[b].pNum;
            switch (pType) {
                // the macro for adding a line segment adds one too many prims
                case D3DPT_LINESTRIP: batchSize = primCount; primCount--; break;
                case D3DPT_LINELIST: batchSize = primCount*2; break;
                default: batchSize = primCount*3; break;
            }
            res = lpD3DDevice->DrawPrimitive(pType, currentVertex, primCount);
            currentVertex += batchSize;
            // init to something it can never be
            batches[b].pType = (D3DPRIMITIVETYPE)0;
            batches[b].pNum = 0;
        }
    } else {
        DebugPrintD3DError(res, "Can't lock vertex buffer");
    }

    // REMIND: may need to rethink what to do in case of an error,
    // should we try to render them later?
    if (actionType == RESET_ACTION) {
        firstPendingBatch = 0;
        firstPendingVertex = 0;
        firstUnusedVertex = 0;
        currentBatch = 0;
    } else {
        firstPendingBatch = currentBatch;
        firstPendingVertex = firstUnusedVertex;
    }

    return res;
}
Пример #30
0
static void Win32OSSD_LockByDD(JNIEnv *env, Win32SDOps *wsdo, jint lockflags,
			       SurfaceDataRasInfo *pRasInfo)
{
    DTRACE_PRINTLN("Win32OSSD_LockByDD");
    
    if ((lockflags & SD_LOCK_READ) &&
	!wsdo->surfacePuntData.disablePunts) 
    {
	wsdo->surfacePuntData.numBltsSinceRead = 0;
	if (!wsdo->surfacePuntData.usingDDSystem) {
	    int w = pRasInfo->bounds.x2 - pRasInfo->bounds.x1;
	    int h = pRasInfo->bounds.y2 - pRasInfo->bounds.y1;
	    wsdo->surfacePuntData.pixelsReadSinceBlt += w * h;
	    // Note that basing this decision on the bounds is somewhat
	    // incorrect because locks of type FASTEST will simply send
	    // in bounds that equal the area of the entire surface.
	    // To do this correctly, we would need to return 
	    // SLOWLOCK and recalculate the punt data in GetRasInfo()
	    if (wsdo->surfacePuntData.pixelsReadSinceBlt >
		wsdo->surfacePuntData.pixelsReadThreshold) 
	    {
		// Create the system surface if it doesn't exist
		if (!wsdo->surfacePuntData.lpSurfaceSystem) {
		    wsdo->surfacePuntData.lpSurfaceSystem = 
			wsdo->ddInstance->ddObject->CreateDDOffScreenSurface(
			wsdo->w, wsdo->h, wsdo->depth,
			FALSE /* don't need caps d3d for surfaces in system memory */,
			wsdo->transparency, DDSCAPS_SYSTEMMEMORY);
		    if (wsdo->surfacePuntData.lpSurfaceSystem) {
                        // 4941350: Double-check that the surface we created
                        // matches the depth expected.
                        int sysmemDepth = 
                            wsdo->surfacePuntData.lpSurfaceSystem->GetSurfaceDepth();
                        if (!DDSurfaceDepthsCompatible(wsdo->depth, sysmemDepth)) {
                            // There is clearly a problem here; release
                            // the punting surface
                            J2dTraceLn2(J2D_TRACE_WARNING,
                                        "Punting error: Java/sys depths %d/%d",
                                        wsdo->depth, sysmemDepth);
                            DDReleaseSurfaceMemory(wsdo->surfacePuntData.
                                lpSurfaceSystem);
                            wsdo->surfacePuntData.lpSurfaceSystem = NULL;
                        } else {
                            DDCOLORKEY ddck;
                            HRESULT ddResult = 
                                wsdo->surfacePuntData.lpSurfaceVram->GetColorKey(
                                DDCKEY_SRCBLT, &ddck);
                            if (ddResult == DD_OK) {
                                // Vram surface has colorkey - use same colorkey on sys
                                ddResult = 
                                    wsdo->surfacePuntData.lpSurfaceSystem->SetColorKey(
                                    DDCKEY_SRCBLT, &ddck);
                            }
			}
		    }
		}
		// Assuming no errors in system creation, copy contents
		if (wsdo->surfacePuntData.lpSurfaceSystem) {
		    if (wsdo->surfacePuntData.lpSurfaceSystem->Blt(NULL, 
			    wsdo->surfacePuntData.lpSurfaceVram, NULL, 
			    DDBLT_WAIT, NULL) == DD_OK) 
		    {
			J2dTraceLn2(J2D_TRACE_INFO, 
				    "Win32OSSD: punting VRAM to sys: 0x%x -> 0x%x\n",
				    wsdo->surfacePuntData.lpSurfaceSystem,
				    wsdo->surfacePuntData.lpSurfaceVram);
			wsdo->lpSurface = wsdo->surfacePuntData.lpSurfaceSystem;
			wsdo->surfacePuntData.usingDDSystem = TRUE;
			// Notify the Java level that this surface has
			// been punted to avoid performance penalties from
			// copying from VRAM cached versions of other images
			// when we should use system memory versions instead.
			jobject sdObject =
			    env->NewLocalRef(wsdo->sdOps.sdObject);
			if (sdObject) {
			    // Only bother with this optimization if the
			    // reference is still valid
			    env->SetBooleanField(sdObject, ddSurfacePuntedID,
						 JNI_TRUE);
			    env->DeleteLocalRef(sdObject);
			}
		    }
		}
	    }
	}
    }

    if (!DDLock(env, wsdo, NULL, pRasInfo))
	return;

    wsdo->lockType = WIN32SD_LOCK_BY_DDRAW;
}