/*
 * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "D3DPipeline.h"
#include "jlong.h"

#include "GraphicsPrimitiveMgr.h"
#include "D3DContext.h"
#include "D3DSurfaceData.h"
#include "D3DBufImgOps.h"
#include "D3DPaints.h"
#include "D3DRenderQueue.h"
#include "D3DShaders.h"
#include "D3DTextRenderer.h"
#include "D3DPipelineManager.h"
#include "D3DGlyphCache.h"

typedef struct {
    D3DBLEND src;
    D3DBLEND dst;
} D3DBlendRule;

/**
 * This table contains the standard blending rules (or Porter-Duff compositing
 * factors) used in SetRenderState(), indexed by the rule constants from the
 * AlphaComposite class.
 */
D3DBlendRule StdBlendRules[] = {
    { D3DBLEND_ZERO,         D3DBLEND_ZERO        }, /* 0 - Nothing      */
    { D3DBLEND_ZERO,         D3DBLEND_ZERO        }, /* 1 - RULE_Clear   */
    { D3DBLEND_ONE,          D3DBLEND_ZERO        }, /* 2 - RULE_Src     */
    { D3DBLEND_ONE,          D3DBLEND_INVSRCALPHA }, /* 3 - RULE_SrcOver */
    { D3DBLEND_INVDESTALPHA, D3DBLEND_ONE         }, /* 4 - RULE_DstOver */
    { D3DBLEND_DESTALPHA,    D3DBLEND_ZERO        }, /* 5 - RULE_SrcIn   */
    { D3DBLEND_ZERO,         D3DBLEND_SRCALPHA    }, /* 6 - RULE_DstIn   */
    { D3DBLEND_INVDESTALPHA, D3DBLEND_ZERO        }, /* 7 - RULE_SrcOut  */
    { D3DBLEND_ZERO,         D3DBLEND_INVSRCALPHA }, /* 8 - RULE_DstOut  */
    { D3DBLEND_ZERO,         D3DBLEND_ONE         }, /* 9 - RULE_Dst     */
    { D3DBLEND_DESTALPHA,    D3DBLEND_INVSRCALPHA }, /*10 - RULE_SrcAtop */
    { D3DBLEND_INVDESTALPHA, D3DBLEND_SRCALPHA    }, /*11 - RULE_DstAtop */
    { D3DBLEND_INVDESTALPHA, D3DBLEND_INVSRCALPHA }, /*12 - RULE_AlphaXor*/
};

void
D3DUtils_SetOrthoMatrixOffCenterLH(D3DMATRIX *m,
                                   float width, float height)
{
    ZeroMemory(m, sizeof(D3DMATRIX));
    m->_11 =  2.0f/width;
    m->_22 = -2.0f/height;
    m->_33 =  0.5f;
    m->_44 =  1.0f;

    m->_41 = -1.0f;
    m->_42 =  1.0f;
    m->_43 =  0.5f;
}

void
D3DUtils_SetIdentityMatrix(D3DMATRIX *m)
{
    m->_12 = m->_13 = m->_14 = m->_21 = m->_23 = m->_24 = 0.0f;
    m->_31 = m->_32 = m->_34 = m->_41 = m->_42 = m->_43 = 0.0f;
    m->_11 = m->_22 = m->_33 = m->_44 = 1.0f;
}

// the following methods are copies of the AffineTransform's class
// corresponding methods, with these changes to the indexes:
// 00 -> 11
// 11 -> 22
// 01 -> 21
// 10 -> 12
// 02 -> 41
// 12 -> 42

void
D3DUtils_2DConcatenateM(D3DMATRIX *m, D3DMATRIX *m1)
{
    float M0, M1;
    float T00, T10, T01, T11;
    float T02, T12;

    T00 = m1->_11; T01 = m1->_21; T02 = m1->_41;
    T10 = m1->_12; T11 = m1->_22; T12 = m1->_42;

    M0 = m->_11;
    M1 = m->_21;
    m->_11  = T00 * M0 + T10 * M1;
    m->_21  = T01 * M0 + T11 * M1;
    m->_41 += T02 * M0 + T12 * M1;

    M0 = m->_12;
    M1 = m->_22;
    m->_12  = T00 * M0 + T10 * M1;
    m->_22  = T01 * M0 + T11 * M1;
    m->_42 += T02 * M0 + T12 * M1;
}

#ifdef UPDATE_TX

void
D3DUtils_2DScaleM(D3DMATRIX *m, float sx, float sy)
{
    m->_11 *= sx;
    m->_22 *= sy;
}

void
D3DUtils_2DInvertM(D3DMATRIX *m)
{
    float M11, M21, M41;
    float M12, M22, M42;
    float det;

    M11 = m->_11; M21 = m->_21; M41 = m->_41;
    M12 = m->_12; M22 = m->_22; M42 = m->_42;
    det = M11 * M22 - M21 * M12;
    if (fabs(det) <= 0.0000000001f) {
        memset(m, 0, sizeof(D3DMATRIX));
        return;
    }
    m->_11 =  M22 / det;
    m->_12 = -M12 / det;
    m->_21 = -M21 / det;
    m->_22 =  M11 / det;
    m->_41 = (M21 * M42 - M22 * M41) / det;
    m->_42 = (M12 * M41 - M11 * M42) / det;
}

void
D3DUtils_2DTranslateM(D3DMATRIX *m, float tx, float ty)
{
    m->_41 = tx * m->_11 + ty * m->_21 + m->_41;
    m->_42 = tx * m->_12 + ty * m->_22 + m->_42;
}

void
D3DUtils_2DTransformXY(D3DMATRIX *m, float *px, float *py)
{
    float x = *px;
    float y = *py;

    *px = x * m->_11 + y * m->_21 + m->_41;
    *py = x * m->_12 + y * m->_22 + m->_42;
}

void
D3DUtils_2DInverseTransformXY(D3DMATRIX *m, float *px, float *py)
{
    float x = *px, y = *py;

    x -= m->_41;
    y -= m->_42;

    float det = m->_11 * m->_22 - m->_21 * m->_12;
    if (fabs(det) < 0.0000000001f) {
        *px = 0.0f;
        *py = 0.0f;
    } else {
        *px = (x * m->_22 - y * m->_21) / det;
        *py = (y * m->_11 - x * m->_12) / det;
    }
}

#endif // UPDATE_TX

static void
D3DContext_DisposeShader(jlong programID)
{
    IDirect3DPixelShader9 *shader =
        (IDirect3DPixelShader9 *)jlong_to_ptr(programID);

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext_DisposeShader");

    SAFE_RELEASE(shader);
}

// static
HRESULT
D3DContext::CreateInstance(IDirect3D9 *pd3d9, UINT adapter, D3DContext **ppCtx)
{
    HRESULT res;
    *ppCtx = new D3DContext(pd3d9, adapter);
    if (FAILED(res = (*ppCtx)->InitContext())) {
        delete *ppCtx;
        *ppCtx = NULL;
    }
    return res;
}

D3DContext::D3DContext(IDirect3D9 *pd3d, UINT adapter)
{
    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::D3DContext");
    J2dTraceLn1(J2D_TRACE_VERBOSE, "  pd3d=0x%x", pd3d);
    pd3dObject = pd3d;
    pd3dDevice = NULL;
    adapterOrdinal = adapter;

    pResourceMgr = NULL;
    pMaskCache = NULL;
    pVCacher = NULL;

    pSyncQuery = NULL;
    pSyncRTRes = NULL;
    pStateBlock = NULL;

    D3DC_INIT_SHADER_LIST(convolvePrograms,   MAX_CONVOLVE);
    D3DC_INIT_SHADER_LIST(rescalePrograms,    MAX_RESCALE);
    D3DC_INIT_SHADER_LIST(lookupPrograms,     MAX_LOOKUP);
    D3DC_INIT_SHADER_LIST(basicGradPrograms,  4);
    D3DC_INIT_SHADER_LIST(linearGradPrograms, 8);
    D3DC_INIT_SHADER_LIST(radialGradPrograms, 8);

    pLCDGlyphCache= NULL;
    pGrayscaleGlyphCache= NULL;
    lcdTextProgram = NULL;
    aaPgramProgram = NULL;

    contextCaps = CAPS_EMPTY;
    bBeginScenePending = FALSE;

    ZeroMemory(&devCaps, sizeof(D3DCAPS9));
    ZeroMemory(&curParams, sizeof(curParams));

    extraAlpha = 1.0f;
}

void D3DContext::ReleaseDefPoolResources()
{
    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::ReleaseDefPoolResources");

    EndScene();

    D3DPipelineManager::NotifyAdapterEventListeners(devCaps.AdapterOrdinal,
                                                    DEVICE_RESET);

    contextCaps = CAPS_EMPTY;

    SAFE_RELEASE(pSyncQuery);
    SAFE_RELEASE(pStateBlock);

    if (pVCacher != NULL) {
        pVCacher->ReleaseDefPoolResources();
    }
    if (pMaskCache != NULL) {
        pMaskCache->ReleaseDefPoolResources();
    }
    if (pLCDGlyphCache != NULL) {
        pLCDGlyphCache->ReleaseDefPoolResources();
    }
    if (pGrayscaleGlyphCache != NULL) {
        pGrayscaleGlyphCache->ReleaseDefPoolResources();
    }
    if (pResourceMgr != NULL) {
        if (pSyncRTRes != NULL) {
            pResourceMgr->ReleaseResource(pSyncRTRes);
            pSyncRTRes = NULL;
        }
        pResourceMgr->ReleaseDefPoolResources();
    }
    ZeroMemory(lastTexture, sizeof(lastTexture));
    ZeroMemory(lastTextureColorState, sizeof(lastTextureColorState));
}

void D3DContext::ReleaseContextResources()
{
    J2dTraceLn1(J2D_TRACE_INFO,
                "D3DContext::ReleaseContextResources: pd3dDevice = 0x%x",
                pd3dDevice);

    ReleaseDefPoolResources();

    D3DPipelineManager::NotifyAdapterEventListeners(devCaps.AdapterOrdinal,
                                                    DEVICE_DISPOSED);

    // dispose shader lists
    ShaderList_Dispose(&convolvePrograms);
    ShaderList_Dispose(&rescalePrograms);
    ShaderList_Dispose(&lookupPrograms);
    ShaderList_Dispose(&basicGradPrograms);
    ShaderList_Dispose(&linearGradPrograms);
    ShaderList_Dispose(&radialGradPrograms);

    SAFE_DELETE(pLCDGlyphCache);
    SAFE_DELETE(pGrayscaleGlyphCache);

    SAFE_RELEASE(lcdTextProgram);
    SAFE_RELEASE(aaPgramProgram);

    SAFE_DELETE(pVCacher);
    SAFE_DELETE(pMaskCache);
    SAFE_DELETE(pResourceMgr);
}

D3DContext::~D3DContext() {
    J2dTraceLn2(J2D_TRACE_INFO,
                "~D3DContext: pd3dDevice=0x%x, pd3dObject =0x%x",
                pd3dDevice, pd3dObject);
    ReleaseContextResources();
    SAFE_RELEASE(pd3dDevice);
}

HRESULT
D3DContext::InitDevice(IDirect3DDevice9 *pd3dDevice)
{
    HRESULT res = S_OK;

    pd3dDevice->GetDeviceCaps(&devCaps);

    J2dRlsTraceLn1(J2D_TRACE_INFO,
                   "D3DContext::InitDevice: device %d", adapterOrdinal);

    // disable some of the unneeded and costly d3d functionality
    pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
    pd3dDevice->SetRenderState(D3DRS_LIGHTING,  FALSE);
    pd3dDevice->SetRenderState(D3DRS_CLIPPING,  FALSE);
    pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
    pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE);
    pd3dDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE);
    pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);

    // set the default texture addressing mode
    pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
    pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

    // REMIND: check supported filters with
    // IDirect3D9::CheckDeviceFormat with D3DUSAGE_QUERY_FILTER
    pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
    pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);

    // these states never change
    pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
    pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);

    // init the array of latest textures
    ZeroMemory(lastTexture, sizeof(lastTexture));
    ZeroMemory(lastTextureColorState, sizeof(lastTextureColorState));

    opState = STATE_CHANGE;

    if (pResourceMgr == NULL) {
        res = D3DResourceManager::CreateInstance(this, &pResourceMgr);
    } else {
        res = pResourceMgr->Init(this);
    }
    RETURN_STATUS_IF_FAILED(res);

    if (pVCacher == NULL) {
        res = D3DVertexCacher::CreateInstance(this, &pVCacher);
    } else {
        res = pVCacher->Init(this);
    }
    RETURN_STATUS_IF_FAILED(res);

    if (pMaskCache == NULL) {
        res = D3DMaskCache::CreateInstance(this, &pMaskCache);
    } else{
        res = pMaskCache->Init(this);
    }
    RETURN_STATUS_IF_FAILED(res);

    if (pLCDGlyphCache != NULL) {
        if (FAILED(res = pLCDGlyphCache->Init(this))) {
            // we can live without the cache
            SAFE_DELETE(pLCDGlyphCache);
            res = S_OK;
        }
    }

    if (pGrayscaleGlyphCache != NULL) {
        if (FAILED(res = pGrayscaleGlyphCache->Init(this))) {
            // we can live without the cache
            SAFE_DELETE(pGrayscaleGlyphCache);
            res = S_OK;
        }
    }

    D3DMATRIX tx;
    D3DUtils_SetIdentityMatrix(&tx);
    pd3dDevice->SetTransform(D3DTS_WORLD, &tx);
    bIsIdentityTx = TRUE;

    if (pSyncQuery == NULL) {
        // this is allowed to fail, do not propagate the error
        if (FAILED(pd3dDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pSyncQuery))) {
            J2dRlsTraceLn(J2D_TRACE_WARNING,
                          "D3DContext::InitDevice: sync query not available");
            pSyncQuery = NULL;
        }
    }
    if (pSyncRTRes == NULL) {
        D3DFORMAT format;
        if (FAILED(GetResourceManager()->
                   CreateRTSurface(32, 32, TRUE, TRUE, &format, &pSyncRTRes))) {
            J2dRlsTraceLn(J2D_TRACE_WARNING,
                          "D3DContext::InitDevice: "
                          "error creating sync surface");
        }
    }

    bBeginScenePending = FALSE;

    J2dRlsTraceLn1(J2D_TRACE_INFO,
                   "D3DContext::InitDefice: successfully initialized device %d",
                   adapterOrdinal);

    return res;
}

HRESULT
D3DContext::CheckAndResetDevice()
{
    HRESULT res = E_FAIL;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::CheckAndResetDevice");

    if (pd3dDevice != NULL) {
        if (FAILED(res = pd3dDevice->TestCooperativeLevel())) {
            if (res == D3DERR_DEVICELOST) {
                J2dTraceLn1(J2D_TRACE_VERBOSE, "  device %d is still lost",
                            adapterOrdinal);
                // nothing to be done here, wait for D3DERR_DEVICENOTRESET
                return res;
            } else if (res == D3DERR_DEVICENOTRESET) {
                J2dTraceLn1(J2D_TRACE_VERBOSE, "  device %d needs to be reset",
                            adapterOrdinal);
                res = ResetContext();
            } else {
                // some unexpected error
                DebugPrintD3DError(res, "D3DContext::CheckAndResetDevice: "\
                                   "unknown error %x from TestCooperativeLevel");
            }
        } else {
            J2dTraceLn1(J2D_TRACE_VERBOSE, "  device %d is not lost",
                        adapterOrdinal);
        }
    } else {
        J2dTraceLn(J2D_TRACE_VERBOSE, "  null device");
    }
    return res;
}

HRESULT
D3DContext::ResetContext()
{
    HRESULT res = E_FAIL;

    J2dRlsTraceLn(J2D_TRACE_INFO, "D3DContext::ResetContext");
    if (pd3dDevice != NULL) {
        D3DPRESENT_PARAMETERS newParams;

        newParams = curParams;

        if (newParams.Windowed) {
            // reset to the current display mode if we're windowed,
            // otherwise to the display mode we were in when the device
            // was lost
            newParams.BackBufferFormat = D3DFMT_UNKNOWN;
            newParams.FullScreen_RefreshRateInHz = 0;
            newParams.BackBufferWidth = 0;
            newParams.BackBufferHeight = 0;
        }
        res = ConfigureContext(&newParams);
    }
    return res;
}

HRESULT
D3DContext::ConfigureContext(D3DPRESENT_PARAMETERS *pNewParams)
{
    J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DContext::ConfigureContext device %d",
                   adapterOrdinal);
    HRESULT res = S_OK;
    D3DFORMAT stencilFormat;
    HWND focusHWND = D3DPipelineManager::GetInstance()->GetCurrentFocusWindow();
    D3DDEVTYPE devType = D3DPipelineManager::GetInstance()->GetDeviceType();
    // this is needed so that we can find the stencil buffer format
    if (pNewParams->BackBufferFormat == D3DFMT_UNKNOWN) {
        D3DDISPLAYMODE dm;

        pd3dObject->GetAdapterDisplayMode(adapterOrdinal, &dm);
        pNewParams->BackBufferFormat = dm.Format;
    }

    stencilFormat =
        D3DPipelineManager::GetInstance()->GetMatchingDepthStencilFormat(
            adapterOrdinal,
            pNewParams->BackBufferFormat, pNewParams->BackBufferFormat);

    pNewParams->EnableAutoDepthStencil = TRUE;
    pNewParams->AutoDepthStencilFormat = stencilFormat;

    // do not set device window in the windowed mode, we use additional
    // swap chains for rendering, the default chain is not used. otherwise
    // our scratch focus window will be made visible
    J2dTraceLn1(J2D_TRACE_VERBOSE, "  windowed=%d",pNewParams->Windowed);
    if (pNewParams->Windowed) {
        pNewParams->hDeviceWindow = (HWND)0;
    }

    // The focus window may change when we're entering/exiting the full-screen
    // mode. It may either be set to the default focus window (when there are
    // no more devices in fs mode), or to fs window for another device
    // in fs mode. See D3DPipelineManager::GetCurrentFocusWindow.
    if (pd3dDevice != NULL) {
        D3DDEVICE_CREATION_PARAMETERS cParams;
        pd3dDevice->GetCreationParameters(&cParams);
        if (cParams.hFocusWindow != focusHWND) {
            J2dTraceLn(J2D_TRACE_VERBOSE,
                       "  focus window changed, need to recreate the device");

            // if fs -> windowed, first exit fs, then recreate, otherwise
            // the screen might be left in a different display mode
            if (pNewParams->Windowed && !curParams.Windowed) {
                J2dTraceLn(J2D_TRACE_VERBOSE,
                            "  exiting full-screen mode, reset the device");
                curParams.Windowed = FALSE;
                ReleaseDefPoolResources();
                res = pd3dDevice->Reset(&curParams);

                if (FAILED(res)) {
                    DebugPrintD3DError(res, "D3DContext::ConfigureContext: "\
                                       "cound not reset the device");
                }
            }

            // note that here we should release all device resources, not only
            // thos in the default pool since the device is released
            ReleaseContextResources();
            SAFE_RELEASE(pd3dDevice);
        }
    }

    if (pd3dDevice != NULL) {
        J2dTraceLn(J2D_TRACE_VERBOSE, "  resetting the device");

        ReleaseDefPoolResources();

        if (pNewParams->PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE &&
            !IsImmediateIntervalSupported())
        {
            pNewParams->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
        }

        res = pd3dDevice->Reset(pNewParams);
        if (FAILED(res)) {
            DebugPrintD3DError(res,
                "D3DContext::ConfigureContext: cound not reset the device");
            return res;
        }
        J2dRlsTraceLn1(J2D_TRACE_INFO,
            "D3DContext::ConfigureContext: successfully reset device: %d",
            adapterOrdinal);
    } else {
        D3DCAPS9 d3dCaps;
        DWORD dwBehaviorFlags;

        J2dTraceLn(J2D_TRACE_VERBOSE, "  creating a new device");

        if (FAILED(res = pd3dObject->GetDeviceCaps(adapterOrdinal,
                                                   devType, &d3dCaps)))
        {
            DebugPrintD3DError(res,
                "D3DContext::ConfigureContext: failed to get caps");
            return res;
        }

        if (pNewParams->PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE &&
            !(d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE))
        {
            pNewParams->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
        }

        // not preserving fpu control word could cause issues (4860749)
        dwBehaviorFlags = D3DCREATE_FPU_PRESERVE;

        J2dRlsTrace(J2D_TRACE_VERBOSE,
                    "[V] dwBehaviorFlags=D3DCREATE_FPU_PRESERVE|");
        if (d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
            J2dRlsTrace(J2D_TRACE_VERBOSE,
                        "D3DCREATE_HARDWARE_VERTEXPROCESSING");
            dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
        } else {
            J2dRlsTrace(J2D_TRACE_VERBOSE,
                        "D3DCREATE_SOFTWARE_VERTEXPROCESSING");
            dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
        }
        // Handling focus changes by ourselves proved to be problematic,
        // so we're reverting back to D3D handling
        // dwBehaviorFlags |= D3DCREATE_NOWINDOWCHANGES;
        J2dRlsTrace(J2D_TRACE_VERBOSE,"\n");

        if (FAILED(res = pd3dObject->CreateDevice(adapterOrdinal, devType,
                                                  focusHWND,
                                                  dwBehaviorFlags,
                                                  pNewParams, &pd3dDevice)))
        {
            DebugPrintD3DError(res,
                "D3DContext::ConfigureContext: error creating d3d device");
            return res;
        }
        J2dRlsTraceLn1(J2D_TRACE_INFO,
            "D3DContext::ConfigureContext: successfully created device: %d",
            adapterOrdinal);
        bIsHWRasterizer = (devType == D3DDEVTYPE_HAL);
    }

    curParams = *pNewParams;
    // during the creation of the device d3d modifies this field, we reset
    // it back to 0
    curParams.Flags = 0;

    if (FAILED(res = InitDevice(pd3dDevice))) {
        ReleaseContextResources();
        return res;
    }

    res = InitContextCaps();

    return res;
}

HRESULT
D3DContext::InitContext()
{
    J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DContext::InitContext device %d",
                   adapterOrdinal);

    D3DPRESENT_PARAMETERS params;
    ZeroMemory(&params, sizeof(D3DPRESENT_PARAMETERS));

    params.hDeviceWindow = 0;
    params.Windowed = TRUE;
    params.BackBufferCount = 1;
    params.BackBufferFormat = D3DFMT_UNKNOWN;
    params.SwapEffect = D3DSWAPEFFECT_DISCARD;
    params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

    return ConfigureContext(&params);
}

HRESULT
D3DContext::Sync()
{
    HRESULT res = S_OK;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::Sync");

    if (pSyncQuery != NULL) {
        J2dTrace(J2D_TRACE_VERBOSE, "  flushing the device queue..");
        while (S_FALSE ==
               (res = pSyncQuery->GetData(NULL, 0, D3DGETDATA_FLUSH))) ;
        J2dTrace(J2D_TRACE_VERBOSE, ".. done\n");
    }
    if (pSyncRTRes != NULL) {
        D3DLOCKED_RECT lr;
        IDirect3DSurface9 *pSurface = pSyncRTRes->GetSurface();
        if (SUCCEEDED(pSurface->LockRect(&lr, NULL, D3DLOCK_NOSYSLOCK))) {
            pSurface->UnlockRect();
        }
    }
    return res;
}

HRESULT
D3DContext::SaveState()
{
    HRESULT res;

    RETURN_STATUS_IF_NULL(pd3dDevice, S_OK);

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::SaveState");

    FlushVertexQueue();
    UpdateState(STATE_CHANGE);

    if (pStateBlock != NULL) {
        J2dTraceLn(J2D_TRACE_WARNING,
                   "D3DContext::SaveState: existing state block!");
        SAFE_RELEASE(pStateBlock);
    }

    if (SUCCEEDED(res =
            pd3dDevice->CreateStateBlock(D3DSBT_ALL, &pStateBlock)))
    {
        J2dTraceLn(J2D_TRACE_VERBOSE, "  created state block");
    } else {
        J2dTraceLn(J2D_TRACE_WARNING,
                   "D3DContext::SaveState: failed to create state block");
    }
    ZeroMemory(lastTexture, sizeof(lastTexture));

    return res;
}

HRESULT
D3DContext::RestoreState()
{
    HRESULT res = S_OK;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::RestoreState");

    FlushVertexQueue();
    UpdateState(STATE_CHANGE);

    if (pStateBlock != NULL) {
        if (SUCCEEDED(res = pStateBlock->Apply())) {
            J2dTraceLn(J2D_TRACE_VERBOSE, "  restored device state");
        } else {
            J2dTraceLn(J2D_TRACE_WARNING,
                       "D3DContext::RestoreState: failed to restore state");
        }
        SAFE_RELEASE(pStateBlock);
    } else {
        J2dTraceLn(J2D_TRACE_WARNING,
                   "D3DContext::RestoreState: empty state block!");
    }
    ZeroMemory(lastTexture, sizeof(lastTexture));

    return res;
}

#define POINT_FILTER_CAP (D3DPTFILTERCAPS_MAGFPOINT|D3DPTFILTERCAPS_MINFPOINT)
#define LINEAR_FILTER_CAP (D3DPTFILTERCAPS_MAGFLINEAR|D3DPTFILTERCAPS_MINFLINEAR)

BOOL
D3DContext::IsStretchRectFilteringSupported(D3DTEXTUREFILTERTYPE fType)
{
    if (fType == D3DTEXF_POINT) {
        return ((devCaps.StretchRectFilterCaps & POINT_FILTER_CAP) != 0);
    }
    if (fType == D3DTEXF_LINEAR) {
        return ((devCaps.StretchRectFilterCaps & LINEAR_FILTER_CAP) != 0);
    }
    return FALSE;
}

BOOL
D3DContext::IsTextureFilteringSupported(D3DTEXTUREFILTERTYPE fType)
{
    if (fType == D3DTEXF_POINT) {
        return ((devCaps.TextureFilterCaps & POINT_FILTER_CAP) != 0);
    }
    if (fType == D3DTEXF_LINEAR) {
        return ((devCaps.TextureFilterCaps & LINEAR_FILTER_CAP) != 0);
    }
    return FALSE;
}

BOOL
D3DContext::IsTextureFormatSupported(D3DFORMAT format, DWORD usage)
{
    HRESULT hr = pd3dObject->CheckDeviceFormat(adapterOrdinal,
                                               devCaps.DeviceType,
                                               curParams.BackBufferFormat,
                                               usage,
                                               D3DRTYPE_TEXTURE,
                                               format);
    return SUCCEEDED( hr );
}

BOOL
D3DContext::IsDepthStencilBufferOk(D3DSURFACE_DESC *pTargetDesc)
{
    IDirect3DSurface9 *pStencil;
    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::IsDepthStencilBufferOk");

    if (SUCCEEDED(pd3dDevice->GetDepthStencilSurface(&pStencil))) {
        D3DSURFACE_DESC descStencil;
        pStencil->GetDesc(&descStencil);
        pStencil->Release();

        D3DDISPLAYMODE dm;
        return
            (SUCCEEDED(pd3dDevice->GetDisplayMode(0, &dm)) &&
             pTargetDesc->Width <= descStencil.Width &&
             pTargetDesc->Height <= descStencil.Height &&
             SUCCEEDED(pd3dObject->CheckDepthStencilMatch(
                   adapterOrdinal,
                   devCaps.DeviceType,
                   dm.Format, pTargetDesc->Format,
                   descStencil.Format)));
    }
    J2dTraceLn(J2D_TRACE_VERBOSE,
        "  current stencil buffer is not compatible with new Render Target");

    return false;
}



HRESULT
D3DContext::InitDepthStencilBuffer(D3DSURFACE_DESC *pTargetDesc)
{
    HRESULT res;
    IDirect3DSurface9 *pBB;
    D3DDISPLAYMODE dm;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::InitDepthStencilBuffer");

    if (FAILED(res = pd3dDevice->GetDisplayMode(0, &dm))) {
        return res;
    }

    D3DFORMAT newFormat =
        D3DPipelineManager::GetInstance()->GetMatchingDepthStencilFormat(
            adapterOrdinal, dm.Format, pTargetDesc->Format);

    res = pd3dDevice->CreateDepthStencilSurface(
        pTargetDesc->Width, pTargetDesc->Height,
        newFormat, D3DMULTISAMPLE_NONE, 0, false, &pBB, 0);
    if (SUCCEEDED(res)) {
        res = pd3dDevice->SetDepthStencilSurface(pBB);
        pBB->Release();
    }

    return res;
}


HRESULT
D3DContext::SetRenderTarget(IDirect3DSurface9 *pSurface)
{
    static D3DMATRIX tx;
    HRESULT res;
    D3DSURFACE_DESC descNew;
    IDirect3DSurface9 *pCurrentTarget;

    J2dTraceLn1(J2D_TRACE_INFO,
                "D3DContext::SetRenderTarget: pSurface=0x%x",
                pSurface);

    RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL);
    RETURN_STATUS_IF_NULL(pSurface, E_FAIL);

    pSurface->GetDesc(&descNew);

    if (SUCCEEDED(res = pd3dDevice->GetRenderTarget(0, &pCurrentTarget))) {
        if (pCurrentTarget != pSurface) {
            FlushVertexQueue();
            if (FAILED(res = pd3dDevice->SetRenderTarget(0, pSurface))) {
                DebugPrintD3DError(res, "D3DContext::SetRenderTarget: "\
                                        "error setting render target");
                SAFE_RELEASE(pCurrentTarget);
                return res;
            }

            if (!IsDepthStencilBufferOk(&descNew)) {
                if (FAILED(res = InitDepthStencilBuffer(&descNew))) {
                    SAFE_RELEASE(pCurrentTarget);
                    return res;
                }
            }
        }
        SAFE_RELEASE(pCurrentTarget);
    }
    // we set the transform even if the render target didn't change;
    // this is because in some cases (fs mode) we use the default SwapChain of
    // the device, and its render target will be the same as the device's, and
    // we have to set the matrix correctly. This shouldn't be a performance
    // issue as render target changes are relatively rare
    D3DUtils_SetOrthoMatrixOffCenterLH(&tx,
                       (float)descNew.Width,
                       (float)descNew.Height);
    pd3dDevice->SetTransform(D3DTS_PROJECTION, &tx);

    J2dTraceLn1(J2D_TRACE_VERBOSE, "  current render target=0x%x", pSurface);
    return res;
}

HRESULT
D3DContext::ResetTransform()
{
    HRESULT res = S_OK;
    D3DMATRIX tx;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::ResetTransform");
    if (pd3dDevice == NULL) {
        return E_FAIL;
    }

    // no need for state change, just flush the queue
    FlushVertexQueue();

    D3DUtils_SetIdentityMatrix(&tx);
    if (FAILED(res = pd3dDevice->SetTransform(D3DTS_WORLD, &tx))) {
        DebugPrintD3DError(res, "D3DContext::SetTransform failed");
    }
    bIsIdentityTx = TRUE;
    return res;
}

HRESULT
D3DContext::SetTransform(jdouble m00, jdouble m10,
                         jdouble m01, jdouble m11,
                         jdouble m02, jdouble m12)
{
    HRESULT res = S_OK;
    D3DMATRIX tx, tx1;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::SetTransform");
    if (pd3dDevice == NULL) {
        return E_FAIL;
    }

    // no need for state change, just flush the queue
    FlushVertexQueue();

    // In order to correctly map texels to pixels we need to
    // adjust geometry by -0.5f in the transformed space.
    // In order to do that we first create a translated matrix
    // and then concatenate it with the world transform.
    //
    // Note that we only use non-id transform with DrawTexture,
    // the rest is rendered pre-transformed.
    //
    // The identity transform for textures is handled in
    // D3DVertexCacher::DrawTexture() because shifting by -0.5 for id
    // transform breaks lines rendering.

    ZeroMemory(&tx1, sizeof(D3DMATRIX));

    tx1._11 = (float)m00;
    tx1._12 = (float)m10;
    tx1._21 = (float)m01;
    tx1._22 = (float)m11;
    tx1._41 = (float)m02;
    tx1._42 = (float)m12;

    tx1._33 = 1.0f;
    tx1._44 = 1.0f;

    D3DUtils_SetIdentityMatrix(&tx);
    tx._41 = -0.5f;
    tx._42 = -0.5f;
    D3DUtils_2DConcatenateM(&tx, &tx1);

    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  %5f %5f %5f %5f", tx._11, tx._12, tx._13, tx._14);
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  %5f %5f %5f %5f", tx._21, tx._22, tx._23, tx._24);
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  %5f %5f %5f %5f", tx._31, tx._32, tx._33, tx._34);
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  %5f %5f %5f %5f", tx._41, tx._42, tx._43, tx._44);
    if (FAILED(res = pd3dDevice->SetTransform(D3DTS_WORLD, &tx))) {
        DebugPrintD3DError(res, "D3DContext::SetTransform failed");
    }
    bIsIdentityTx = FALSE;

    return res;
}

HRESULT
D3DContext::SetRectClip(int x1, int y1, int x2, int y2)
{
    HRESULT res = S_OK;
    D3DSURFACE_DESC desc;
    IDirect3DSurface9 *pCurrentTarget;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::SetRectClip");
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  x1=%-4d y1=%-4d x2=%-4d y2=%-4d",
                x1, y1, x2, y2);

    RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL);

    // no need for state change, just flush the queue
    FlushVertexQueue();

    pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);

    res = pd3dDevice->GetRenderTarget(0, &pCurrentTarget);
    RETURN_STATUS_IF_FAILED(res);

    pCurrentTarget->GetDesc(&desc);
    SAFE_RELEASE(pCurrentTarget);

    if (x1 <= 0 && y1 <= 0 &&
        (UINT)x2 >= desc.Width && (UINT)y2 >= desc.Height)
    {
        J2dTraceLn(J2D_TRACE_VERBOSE,
                   "  disabling clip (== render target dimensions)");
        return pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
    }

    // clip to the dimensions of the target surface, otherwise
    // SetScissorRect will fail
    if (x1 < 0)                 x1 = 0;
    if (y1 < 0)                 y1 = 0;
    if ((UINT)x2 > desc.Width)  x2 = desc.Width;
    if ((UINT)y2 > desc.Height) y2 = desc.Height;
    if (x1 > x2)                x2 = x1 = 0;
    if (y1 > y2)                y2 = y1 = 0;
    RECT newRect = { x1, y1, x2, y2 };
    if (SUCCEEDED(res = pd3dDevice->SetScissorRect(&newRect))) {
        res = pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
    } else {
        DebugPrintD3DError(res, "Error setting scissor rect");
        J2dRlsTraceLn4(J2D_TRACE_ERROR,
                       "  x1=%-4d y1=%-4d x2=%-4d y2=%-4d",
                       x1, y1, x2, y2);
    }

    return res;
}

HRESULT
D3DContext::ResetClip()
{
    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::ResetClip");
    // no need for state change, just flush the queue
    FlushVertexQueue();
    pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
    return pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
}

ClipType
D3DContext::GetClipType()
{
    // REMIND: this method could be optimized: we could keep the
    // clip state around when re/setting the clip instead of asking
    // every time.
    DWORD zEnabled = 0;
    DWORD stEnabled = 0;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::GetClipType");
    pd3dDevice->GetRenderState(D3DRS_SCISSORTESTENABLE, &stEnabled);
    if (stEnabled) {
        return CLIP_RECT;
    }
    pd3dDevice->GetRenderState(D3DRS_ZENABLE, &zEnabled);
    if (zEnabled) {
        return CLIP_SHAPE;
    }
    return CLIP_NONE;
}


/**
 * This method assumes that ::SetRenderTarget has already
 * been called. SetRenderTarget creates and attaches a
 * depth buffer to the target surface prior to setting it
 * as target surface to the device.
 */
DWORD dwAlphaSt, dwSrcBlendSt, dwDestBlendSt;
D3DMATRIX tx, idTx;

HRESULT
D3DContext::BeginShapeClip()
{
    HRESULT res = S_OK;
    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::BeginShapeClip");

    UpdateState(STATE_CHANGE);

    pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);

    // save alpha blending state
    pd3dDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &dwAlphaSt);
    pd3dDevice->GetRenderState(D3DRS_SRCBLEND, &dwSrcBlendSt);
    pd3dDevice->GetRenderState(D3DRS_DESTBLEND, &dwDestBlendSt);

    pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
    pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

    pd3dDevice->GetTransform(D3DTS_WORLD, &tx);
    D3DUtils_SetIdentityMatrix(&idTx);
    // translate the clip spans by 1.0f in z direction so that the
    // clip spans are rendered to the z buffer
    idTx._43 = 1.0f;
    pd3dDevice->SetTransform(D3DTS_WORLD, &idTx);

    // The depth buffer is first cleared with zeroes, which is the farthest
    // plane from the viewer (our projection matrix is an inversed orthogonal
    // transform).
    // To set the clip we'll render the clip spans with Z coordinates of 1.0f
    // (the closest to the viewer). Since all rendering primitives
    // have their vertices' Z coordinate set to 0.0, they will effectively be
    // clipped because the Z depth test for them will fail (vertex with 1.0
    // depth is closer than the one with 0.0f)
    pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
    pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
    pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
    pd3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0L, 0.0f, 0x0L);

    //res = BeginScene(STATE_SHAPE_CLIPOP);

    return res;
}

HRESULT
D3DContext::EndShapeClip()
{
    HRESULT res;

    // no need for state change, just flush the queue
    res = FlushVertexQueue();

    // restore alpha blending state
    pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, dwAlphaSt);
    pd3dDevice->SetRenderState(D3DRS_SRCBLEND, dwSrcBlendSt);
    pd3dDevice->SetRenderState(D3DRS_DESTBLEND, dwDestBlendSt);

    // resore the transform
    pd3dDevice->SetTransform(D3DTS_WORLD, &tx);

    // Enable the depth buffer.
    // We disable further updates to the depth buffer: it should only
    // be updated in SetClip method.
    pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
    pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);

    return res;
}

HRESULT
D3DContext::UploadTileToTexture(D3DResource *pTextureRes, void *pixels,
                                jint dstx, jint dsty,
                                jint srcx, jint srcy,
                                jint srcWidth, jint srcHeight,
                                jint srcStride,
                                TileFormat srcFormat,
                                jint *pPixelsTouchedL,
                                jint* pPixelsTouchedR)
{
#ifndef PtrAddBytes
#define PtrAddBytes(p, b)               ((void *) (((intptr_t) (p)) + (b)))
#define PtrCoord(p, x, xinc, y, yinc)   PtrAddBytes(p, (y)*(yinc) + (x)*(xinc))
#endif // PtrAddBytes

    HRESULT res = S_OK;
    IDirect3DTexture9 *pTexture = pTextureRes->GetTexture();
    D3DSURFACE_DESC *pDesc = pTextureRes->GetDesc();
    RECT r = { dstx, dsty, dstx+srcWidth, dsty+srcHeight };
    RECT *pR = &r;
    D3DLOCKED_RECT lockedRect;
    DWORD dwLockFlags = D3DLOCK_NOSYSLOCK;
    // these are only counted for LCD glyph uploads
    jint pixelsTouchedL = 0, pixelsTouchedR = 0;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::UploadTileToTexture");
    J2dTraceLn4(J2D_TRACE_VERBOSE,
        " rect={%-4d, %-4d, %-4d, %-4d}",
        r.left, r.top, r.right, r.bottom);

    if (pDesc->Usage == D3DUSAGE_DYNAMIC) {
        // it is safe to lock with discard because we don't care about the
        // contents of dynamic textures and dstx,dsty for this case is
        // always 0,0 because we are uploading into a tile texture
        dwLockFlags |= D3DLOCK_DISCARD;
        pR = NULL;
    }

    if (FAILED(res = pTexture->LockRect(0, &lockedRect, pR, dwLockFlags))) {
        DebugPrintD3DError(res,
            "D3DContext::UploadImageToTexture: could "\
            "not lock texture");
        return res;
    }

    if (srcFormat == TILEFMT_1BYTE_ALPHA) {
        // either a MaskFill tile, or a grayscale glyph
        if (pDesc->Format == D3DFMT_A8) {
            void *pSrcPixels = PtrCoord(pixels, srcx, 1, srcy, srcStride);
            void *pDstPixels = lockedRect.pBits;
            do {
                memcpy(pDstPixels, pSrcPixels, srcWidth);
                pSrcPixels = PtrAddBytes(pSrcPixels, srcStride);
                pDstPixels = PtrAddBytes(pDstPixels, lockedRect.Pitch);
            } while (--srcHeight > 0);
        }
        else if (pDesc->Format == D3DFMT_A8R8G8B8) {
            jubyte *pSrcPixels = (jubyte*)
                PtrCoord(pixels, srcx, 1, srcy, srcStride);
            jint *pDstPixels = (jint*)lockedRect.pBits;
            for (int yy = 0; yy < srcHeight; yy++) {
                for (int xx = 0; xx < srcWidth; xx++) {
                    // only need to set the alpha channel (the D3D texture
                    // state will be setup in this case to replicate the
                    // alpha channel as needed)
                    pDstPixels[xx] = pSrcPixels[xx] << 24;
                }
                pSrcPixels = (jubyte*)PtrAddBytes(pSrcPixels, srcStride);
                pDstPixels = (jint*)PtrAddBytes(pDstPixels, lockedRect.Pitch);
            }
        }
    } else if (srcFormat == TILEFMT_3BYTE_RGB) {
        // LCD glyph with RGB order
        if (pDesc->Format == D3DFMT_R8G8B8) {
            jubyte *pSrcPixels = (jubyte*)
                PtrCoord(pixels, srcx, 3, srcy, srcStride);
            jubyte *pDstPixels = (jubyte*)lockedRect.pBits;
            for (int yy = 0; yy < srcHeight; yy++) {
                for (int xx = 0; xx < srcWidth*3; xx+=3) {
                    // alpha channel is ignored in this case
                    // (note that this is backwards from what one might
                    // expect; it appears that D3DFMT_R8G8B8 is actually
                    // laid out in BGR order in memory)
                    pDstPixels[xx+0] = pSrcPixels[xx+2];
                    pDstPixels[xx+1] = pSrcPixels[xx+1];
                    pDstPixels[xx+2] = pSrcPixels[xx+0];
                }
                pixelsTouchedL +=
                    (pDstPixels[0+0]|pDstPixels[0+1]|pDstPixels[0+2]) ? 1 : 0;
                jint i = 3*(srcWidth-1);
                pixelsTouchedR +=
                    (pDstPixels[i+0]|pDstPixels[i+1]|pDstPixels[i+2]) ? 1 : 0;

                pSrcPixels = (jubyte*)PtrAddBytes(pSrcPixels, srcStride);
                pDstPixels = (jubyte*)PtrAddBytes(pDstPixels, lockedRect.Pitch);
            }
        }
        else if (pDesc->Format == D3DFMT_A8R8G8B8) {
            jubyte *pSrcPixels = (jubyte*)
                PtrCoord(pixels, srcx, 3, srcy, srcStride);
            jint *pDstPixels = (jint*)lockedRect.pBits;
            for (int yy = 0; yy < srcHeight; yy++) {
                for (int dx = 0, sx = 0; dx < srcWidth; dx++, sx+=3) {
                    // alpha channel is ignored in this case
                    jubyte r = pSrcPixels[sx+0];
                    jubyte g = pSrcPixels[sx+1];
                    jubyte b = pSrcPixels[sx+2];
                    pDstPixels[dx] = (r << 16) | (g << 8) | (b);
                }
                pixelsTouchedL += (pDstPixels[0]          ? 1 : 0);
                pixelsTouchedR += (pDstPixels[srcWidth-1] ? 1 : 0);

                pSrcPixels = (jubyte*)PtrAddBytes(pSrcPixels, srcStride);
                pDstPixels = (jint*)PtrAddBytes(pDstPixels, lockedRect.Pitch);
            }
        }
    } else if (srcFormat == TILEFMT_3BYTE_BGR) {
        // LCD glyph with BGR order
        if (pDesc->Format == D3DFMT_R8G8B8) {
            void *pSrcPixels = PtrCoord(pixels, srcx, 3, srcy, srcStride);
            void *pDstPixels = lockedRect.pBits;
            jubyte *pbDst;
            do {
                // alpha channel is ignored in this case
                // (note that this is backwards from what one might
                // expect; it appears that D3DFMT_R8G8B8 is actually
                // laid out in BGR order in memory)
                memcpy(pDstPixels, pSrcPixels, srcWidth * 3);

                pbDst = (jubyte*)pDstPixels;
                pixelsTouchedL +=(pbDst[0+0]|pbDst[0+1]|pbDst[0+2]) ? 1 : 0;
                jint i = 3*(srcWidth-1);
                pixelsTouchedR +=(pbDst[i+0]|pbDst[i+1]|pbDst[i+2]) ? 1 : 0;

                pSrcPixels = PtrAddBytes(pSrcPixels, srcStride);
                pDstPixels = PtrAddBytes(pDstPixels, lockedRect.Pitch);
            } while (--srcHeight > 0);
        }
        else if (pDesc->Format == D3DFMT_A8R8G8B8) {
            jubyte *pSrcPixels = (jubyte*)
                PtrCoord(pixels, srcx, 3, srcy, srcStride);
            jint *pDstPixels = (jint*)lockedRect.pBits;
            for (int yy = 0; yy < srcHeight; yy++) {
                for (int dx = 0, sx = 0; dx < srcWidth; dx++, sx+=3) {
                    // alpha channel is ignored in this case
                    jubyte b = pSrcPixels[sx+0];
                    jubyte g = pSrcPixels[sx+1];
                    jubyte r = pSrcPixels[sx+2];
                    pDstPixels[dx] = (r << 16) | (g << 8) | (b);
                }
                pixelsTouchedL += (pDstPixels[0]          ? 1 : 0);
                pixelsTouchedR += (pDstPixels[srcWidth-1] ? 1 : 0);

                pSrcPixels = (jubyte*)PtrAddBytes(pSrcPixels, srcStride);
                pDstPixels = (jint*)PtrAddBytes(pDstPixels, lockedRect.Pitch);
            }
        }
    } else if (srcFormat == TILEFMT_4BYTE_ARGB_PRE) {
        // MaskBlit tile
        if (pDesc->Format == D3DFMT_A8R8G8B8) {
            void *pSrcPixels = PtrCoord(pixels, srcx, 4, srcy, srcStride);
            void *pDstPixels = lockedRect.pBits;
            do {
                memcpy(pDstPixels, pSrcPixels, srcWidth * 4);
                pSrcPixels = PtrAddBytes(pSrcPixels, srcStride);
                pDstPixels = PtrAddBytes(pDstPixels, lockedRect.Pitch);
            } while (--srcHeight > 0);
        }
    } else {
        // should not happen, no-op just in case...
    }

    if (pPixelsTouchedL) {
        *pPixelsTouchedL  = pixelsTouchedL;
    }
    if (pPixelsTouchedR) {
        *pPixelsTouchedR = pixelsTouchedR;
    }

    return pTexture->UnlockRect(0);
}

HRESULT
D3DContext::InitLCDGlyphCache()
{
    if (pLCDGlyphCache == NULL) {
        return D3DGlyphCache::CreateInstance(this, CACHE_LCD, &pLCDGlyphCache);
    }
    return S_OK;
}

HRESULT
D3DContext::InitGrayscaleGlyphCache()
{
    if (pGrayscaleGlyphCache == NULL) {
        return D3DGlyphCache::CreateInstance(this, CACHE_GRAY,
                                             &pGrayscaleGlyphCache);
    }
    return S_OK;
}

HRESULT
D3DContext::ResetComposite()
{
    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::ResetComposite");

    RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL);

    HRESULT res = UpdateState(STATE_CHANGE);
    pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    extraAlpha = 1.0f;
    return res;
}

HRESULT
D3DContext::SetAlphaComposite(jint rule, jfloat ea, jint flags)
{
    HRESULT res;
    J2dTraceLn3(J2D_TRACE_INFO,
                "D3DContext::SetAlphaComposite: rule=%-1d ea=%f flags=%d",
                rule, ea, flags);

    RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL);

    res = UpdateState(STATE_CHANGE);

    // 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) &&
        (ea == 1.0f) &&
        (flags & D3DC_SRC_IS_OPAQUE))
    {
        J2dTraceLn1(J2D_TRACE_VERBOSE,
                    "  disabling alpha comp rule=%-1d ea=1.0 src=opq)", rule);
        pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    } else {
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "  enabling alpha comp (rule=%-1d ea=%f)", rule, ea);
        pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

        pd3dDevice->SetRenderState(D3DRS_SRCBLEND,
                                   StdBlendRules[rule].src);
        pd3dDevice->SetRenderState(D3DRS_DESTBLEND,
                                   StdBlendRules[rule].dst);
    }

    extraAlpha = ea;
    return res;
}

#ifdef UPDATE_TX

// Note: this method of adjusting pixel to texel mapping proved to be
// difficult to perfect. The current variation works great for id,
// scale (including all kinds of flips) transforms, but not still not
// for generic transforms.
//
// Since we currently only do DrawTexture with non-id transform we instead
// adjust the geometry (see D3DVertexCacher::DrawTexture(), SetTransform())
//
// In order to enable this code path UpdateTextureTransforms needs to
// be called in SetTexture(), SetTransform() and ResetTranform().
HRESULT
D3DContext::UpdateTextureTransforms(DWORD dwSamplerToUpdate)
{
    HRESULT res = S_OK;
    DWORD dwSampler, dwMaxSampler;

    if (dwSamplerToUpdate == -1) {
        // update all used samplers, dwMaxSampler will be set to max
        dwSampler = 0;
        dwSampler = MAX_USED_TEXTURE_SAMPLER;
        J2dTraceLn(J2D_TRACE_INFO, "D3DContext::UpdateTextureTransforms: "\
                                   "updating all samplers");
    } else {
        // update only given sampler, dwMaxSampler will be set to it as well
        dwSampler = dwSamplerToUpdate;
        dwMaxSampler = dwSamplerToUpdate;
        J2dTraceLn1(J2D_TRACE_INFO, "D3DContext::UpdateTextureTransforms: "\
                                    "updating sampler %d", dwSampler);
    }

    do {
        D3DTRANSFORMSTATETYPE state =
            (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + dwSampler);
        IDirect3DTexture9 *pTexture = lastTexture[dwSampler];

        if (pTexture != NULL) {
            D3DMATRIX mt, tx;
            D3DSURFACE_DESC texDesc;

            pd3dDevice->GetTransform(D3DTS_WORLD, &tx);
            J2dTraceLn4(10,
                        "  %5f %5f %5f %5f", tx._11, tx._12, tx._13, tx._14);
            J2dTraceLn4(10,
                        "  %5f %5f %5f %5f", tx._21, tx._22, tx._23, tx._24);
            J2dTraceLn4(10,
                        "  %5f %5f %5f %5f", tx._31, tx._32, tx._33, tx._34);
            J2dTraceLn4(10,
                        "  %5f %5f %5f %5f", tx._41, tx._42, tx._43, tx._44);

            // this formula works for scales and flips
            if (tx._11 == 0.0f) {
                tx._11 = tx._12;
            }
            if (tx._22 == 0.0f) {
                tx._22 = tx._21;
            }

            pTexture->GetLevelDesc(0, &texDesc);

            // shift by .5 texel, but take into account
            // the scale factor of the device transform

            // REMIND: this approach is not entirely correct,
            // as it only takes into account the scale of the device
            // transform.
            mt._31 = (1.0f / (2.0f * texDesc.Width  * tx._11));
            mt._32 = (1.0f / (2.0f * texDesc.Height * tx._22));
            J2dTraceLn2(J2D_TRACE_VERBOSE, "  offsets: tx=%f ty=%f",
                        mt._31, mt._32);

            pd3dDevice->SetTextureStageState(dwSampler,
                                             D3DTSS_TEXTURETRANSFORMFLAGS,
                                             D3DTTFF_COUNT2);
            res = pd3dDevice->SetTransform(state, &mt);
        } else {
            res = pd3dDevice->SetTextureStageState(dwSampler,
                                                   D3DTSS_TEXTURETRANSFORMFLAGS,
                                                   D3DTTFF_DISABLE);
        }
        dwSampler++;
    } while (dwSampler <= dwMaxSampler);

    return res;
}
#endif // UPDATE_TX

/**
 * We go into the pains of maintaining the list of set textures
 * instead of just calling GetTexture() and comparing the old one
 * with the new one because it's actually noticeably slower to call
 * GetTexture() (note that we'd have to then call Release() on the
 * texture since GetTexture() increases texture's ref. count).
 */
HRESULT
D3DContext::SetTexture(IDirect3DTexture9 *pTexture, DWORD dwSampler)
{
    HRESULT res = S_OK;
    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::SetTexture");

    if (dwSampler < 0 || dwSampler > MAX_USED_TEXTURE_SAMPLER) {
        J2dTraceLn1(J2D_TRACE_ERROR,
                    "D3DContext::SetTexture: incorrect sampler: %d", dwSampler);
        return E_FAIL;
    }
    if (lastTexture[dwSampler] != pTexture) {
        if (FAILED(res = FlushVertexQueue())) {
            return res;
        }
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "  new texture=0x%x on sampler %d", pTexture, dwSampler);
        res = pd3dDevice->SetTexture(dwSampler, pTexture);
        if (SUCCEEDED(res)) {
            lastTexture[dwSampler] = pTexture;
            // REMIND: see comment at UpdateTextureTransforms
#ifdef UPDATE_TX
            res = UpdateTextureTransforms(dwSampler);
#endif
        }  else {
            lastTexture[dwSampler] = NULL;
        }
    }
    return res;
}

HRESULT
D3DContext::UpdateTextureColorState(DWORD dwState, DWORD dwSampler)
{
    HRESULT res = S_OK;

    if (dwState != lastTextureColorState[dwSampler]) {
        res = pd3dDevice->SetTextureStageState(dwSampler,
                                               D3DTSS_ALPHAARG1, dwState);
        res = pd3dDevice->SetTextureStageState(dwSampler,
                                               D3DTSS_COLORARG1, dwState);
        lastTextureColorState[dwSampler] = dwState;
    }

    return res;
}

HRESULT /*NOLOCK*/
D3DContext::UpdateState(jbyte newState)
{
    HRESULT res = S_OK;

    if (opState == newState) {
        // The op is the same as last time, so we can return immediately.
        return res;
    } else if (opState != STATE_CHANGE) {
        res = FlushVertexQueue();
    }

    switch (opState) {
    case STATE_MASKOP:
        pMaskCache->Disable();
        break;
    case STATE_GLYPHOP:
        D3DTR_DisableGlyphVertexCache(this);
        break;
    case STATE_TEXTUREOP:
        // optimization: certain state changes (those marked STATE_CHANGE)
        // are allowed while texturing is enabled.
        // In this case, we can allow previousOp to remain as it is and
        // then return early.
        if (newState == STATE_CHANGE) {
            return res;
        }
        // REMIND: not necessary if we are switching to MASKOP or GLYPHOP
        // (or a complex paint, for that matter), but would that be a
        // worthwhile optimization?
        SetTexture(NULL);
        break;
    case STATE_AAPGRAMOP:
        res = DisableAAParallelogramProgram();
        break;
    default:
        break;
    }

    switch (newState) {
    case STATE_MASKOP:
        pMaskCache->Enable();
        UpdateTextureColorState(D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE);
        break;
    case STATE_GLYPHOP:
        D3DTR_EnableGlyphVertexCache(this);
        UpdateTextureColorState(D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE);
        break;
    case STATE_TEXTUREOP:
        UpdateTextureColorState(D3DTA_TEXTURE);
        break;
    case STATE_AAPGRAMOP:
        res = EnableAAParallelogramProgram();
        break;
    default:
        break;
    }

    opState = newState;

    return res;
}

HRESULT D3DContext::FlushVertexQueue()
{
    if (pVCacher != NULL) {
        return pVCacher->Render();
    }
    return E_FAIL;
}

HRESULT D3DContext::BeginScene(jbyte newState)
{
    if (!pd3dDevice) {
        return E_FAIL;
    } else {
        UpdateState(newState);
        if (!bBeginScenePending) {
            bBeginScenePending = TRUE;
            HRESULT res = pd3dDevice->BeginScene();
            J2dTraceLn(J2D_TRACE_INFO, "D3DContext::BeginScene");
            if (FAILED(res)) {
                // this will cause context reinitialization
                opState = STATE_CHANGE;
            }
            return res;
        }
        return S_OK;
    }
}

HRESULT D3DContext::EndScene() {
    if (bBeginScenePending) {
        FlushVertexQueue();
        bBeginScenePending = FALSE;
        J2dTraceLn(J2D_TRACE_INFO, "D3DContext::EndScene");
        return pd3dDevice->EndScene();
    }
    return S_OK;
}

/**
 * Compiles and links the given fragment shader program.  If
 * successful, this function returns a handle to the newly created shader
 * program; otherwise returns 0.
 */
IDirect3DPixelShader9 *D3DContext::CreateFragmentProgram(DWORD **shaders,
                                                       ShaderList *programs,
                                                       jint flags)
{
    DWORD *sourceCode;
    IDirect3DPixelShader9 *pProgram;

    J2dTraceLn1(J2D_TRACE_INFO,
                "D3DContext::CreateFragmentProgram: flags=%d",
                flags);

    sourceCode = shaders[flags];
    if (FAILED(pd3dDevice->CreatePixelShader(sourceCode, &pProgram))) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "D3DContext::CreateFragmentProgram: error creating program");
        return NULL;
    }

    // add it to the cache
    ShaderList_AddProgram(programs, ptr_to_jlong(pProgram),
                          0 /*unused*/, 0 /*unused*/, flags);

    return pProgram;
}

/**
 * Locates and enables a fragment program given a list of shader programs
 * (ShaderInfos), using this context's state and flags as search
 * parameters.  The "flags" parameter is a bitwise-or'd value that helps
 * differentiate one program for another; the interpretation of this value
 * varies depending on the type of shader (BufImgOp, Paint, etc) but here
 * it is only used to find another ShaderInfo with that same "flags" value.
 */
HRESULT D3DContext::EnableFragmentProgram(DWORD **shaders,
                                          ShaderList *programList,
                                          jint flags)
{
    HRESULT res;
    jlong programID;
    IDirect3DPixelShader9 *pProgram;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::EnableFragmentProgram");

    programID =
        ShaderList_FindProgram(programList,
                               0 /*unused*/, 0 /*unused*/, flags);

    pProgram = (IDirect3DPixelShader9 *)jlong_to_ptr(programID);
    if (pProgram == NULL) {
        pProgram = CreateFragmentProgram(shaders, programList, flags);
        if (pProgram == NULL) {
            return E_FAIL;
        }
    }

    if (FAILED(res = pd3dDevice->SetPixelShader(pProgram))) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "D3DContext::EnableFragmentProgram: error setting pixel shader");
        return res;
    }

    return S_OK;
}

HRESULT D3DContext::EnableBasicGradientProgram(jint flags)
{
    return EnableFragmentProgram((DWORD **)gradShaders,
                                 &basicGradPrograms, flags);
}

HRESULT D3DContext::EnableLinearGradientProgram(jint flags)
{
    return EnableFragmentProgram((DWORD **)linearShaders,
                                 &linearGradPrograms, flags);
}

HRESULT D3DContext::EnableRadialGradientProgram(jint flags)
{
    return EnableFragmentProgram((DWORD **)radialShaders,
                                 &radialGradPrograms, flags);
}

HRESULT D3DContext::EnableConvolveProgram(jint flags)
{
    return EnableFragmentProgram((DWORD **)convolveShaders,
                                 &convolvePrograms, flags);
}

HRESULT D3DContext::EnableRescaleProgram(jint flags)
{
    return EnableFragmentProgram((DWORD **)rescaleShaders,
                                 &rescalePrograms, flags);
}

HRESULT D3DContext::EnableLookupProgram(jint flags)
{
    return EnableFragmentProgram((DWORD **)lookupShaders,
                                 &lookupPrograms, flags);
}

HRESULT D3DContext::EnableLCDTextProgram()
{
    HRESULT res;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::EnableLCDTextProgram");

    if (lcdTextProgram == NULL) {
        if (FAILED(res = pd3dDevice->CreatePixelShader(lcdtext0,
                                                       &lcdTextProgram)))
        {
            return res;
        }
    }

    if (FAILED(res = pd3dDevice->SetPixelShader(lcdTextProgram))) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "D3DContext::EnableLCDTextProgram: error setting pixel shader");
        return res;
    }

    return S_OK;
}

HRESULT D3DContext::EnableAAParallelogramProgram()
{
    HRESULT res;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::EnableAAParallelogramProgram");

    if (aaPgramProgram == NULL) {
        if (FAILED(res = pd3dDevice->CreatePixelShader(aapgram0,
                                                       &aaPgramProgram))) {
            DebugPrintD3DError(res, "D3DContext::EnableAAParallelogramProgram: "
                               "error creating pixel shader");
            return res;
        }
    }

    if (FAILED(res = pd3dDevice->SetPixelShader(aaPgramProgram))) {
        DebugPrintD3DError(res, "D3DContext::EnableAAParallelogramProgram: "
                           "error setting pixel shader");
        return res;
    }

    return S_OK;
}

HRESULT D3DContext::DisableAAParallelogramProgram()
{
    HRESULT res;

    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::DisableAAParallelogramProgram");

    if (aaPgramProgram != NULL) {
        if (FAILED(res = pd3dDevice->SetPixelShader(NULL))) {
            DebugPrintD3DError(res,
                               "D3DContext::DisableAAParallelogramProgram: "
                               "error clearing pixel shader");
            return res;
        }
    }

    return S_OK;
}

BOOL D3DContext::IsAlphaRTSurfaceSupported()
{
    HRESULT res = pd3dObject->CheckDeviceFormat(adapterOrdinal,
            devCaps.DeviceType,
            curParams.BackBufferFormat,
            D3DUSAGE_RENDERTARGET,
            D3DRTYPE_SURFACE,
            D3DFMT_A8R8G8B8);
    return SUCCEEDED(res);
}

BOOL D3DContext::IsAlphaRTTSupported()
{
    HRESULT res = pd3dObject->CheckDeviceFormat(adapterOrdinal,
            devCaps.DeviceType,
            curParams.BackBufferFormat,
            D3DUSAGE_RENDERTARGET,
            D3DRTYPE_TEXTURE,
            D3DFMT_A8R8G8B8);
    return SUCCEEDED(res);
}

BOOL D3DContext::IsOpaqueRTTSupported()
{
    HRESULT res = pd3dObject->CheckDeviceFormat(adapterOrdinal,
            devCaps.DeviceType,
            curParams.BackBufferFormat,
            D3DUSAGE_RENDERTARGET,
            D3DRTYPE_TEXTURE,
            curParams.BackBufferFormat);
    return SUCCEEDED(res);
}

HRESULT D3DContext::InitContextCaps() {
    J2dTraceLn(J2D_TRACE_INFO, "D3DContext::InitContextCaps");
    J2dTraceLn1(J2D_TRACE_VERBOSE, "  caps for adapter %d :", adapterOrdinal);

    if (pd3dDevice == NULL || pd3dObject == NULL) {
        contextCaps = CAPS_EMPTY;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_EMPTY");
        return E_FAIL;
    }

    contextCaps = CAPS_DEVICE_OK;
    J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_DEVICE_OK");

    if (IsAlphaRTSurfaceSupported()) {
        contextCaps |= CAPS_RT_PLAIN_ALPHA;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_RT_PLAIN_ALPHA");
    }
    if (IsAlphaRTTSupported()) {
        contextCaps |= CAPS_RT_TEXTURE_ALPHA;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_RT_TEXTURE_ALPHA");
    }
    if (IsOpaqueRTTSupported()) {
        contextCaps |= CAPS_RT_TEXTURE_OPAQUE;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_RT_TEXTURE_OPAQUE");
    }
    if (IsPixelShader20Supported()) {
        contextCaps |= CAPS_LCD_SHADER | CAPS_BIOP_SHADER | CAPS_PS20;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE,
                      "  | CAPS_LCD_SHADER | CAPS_BIOP_SHADER | CAPS_PS20");
        // Pre-PS3.0 video boards are very slow with the AA shader, so
        // we will require PS30 hw even though the shader is compiled for 2.0a
//        if (IsGradientInstructionExtensionSupported()) {
//            contextCaps |= CAPS_AA_SHADER;
//            J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_AA_SHADER");
//        }
    }
    if (IsPixelShader30Supported()) {
        if ((contextCaps & CAPS_AA_SHADER) == 0) {
            // This flag was not already mentioned above...
            J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_AA_SHADER");
        }
        contextCaps |= CAPS_PS30 | CAPS_AA_SHADER;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_PS30");
    }
    if (IsMultiTexturingSupported()) {
        contextCaps |= CAPS_MULTITEXTURE;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_MULTITEXTURE");
    }
    if (!IsPow2TexturesOnly()) {
        contextCaps |= CAPS_TEXNONPOW2;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_TEXNONPOW2");
    }
    if (!IsSquareTexturesOnly()) {
        contextCaps |= CAPS_TEXNONSQUARE;
        J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  | CAPS_TEXNONSQUARE");
    }
    return S_OK;
}
