Esempio n. 1
0
void Display::setSwapInterval(GLint interval)
{
    mSwapInterval = interval;
    mSwapInterval = std::max(mSwapInterval, mMinSwapInterval);
    mSwapInterval = std::min(mSwapInterval, mMaxSwapInterval);

    mPresentInterval = convertInterval(mSwapInterval);
}
Esempio n. 2
0
bool Display::createDevice()
{
    static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
    static const TCHAR className[] = TEXT("STATIC");

    mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);

    D3DPRESENT_PARAMETERS presentParameters = {0};

    // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
    presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
    presentParameters.BackBufferCount = 1;
    presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
    presentParameters.BackBufferWidth = 1;
    presentParameters.BackBufferHeight = 1;
    presentParameters.EnableAutoDepthStencil = FALSE;
    presentParameters.Flags = 0;
    presentParameters.hDeviceWindow = mDeviceWindow;
    presentParameters.MultiSampleQuality = 0;
    presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
    presentParameters.PresentationInterval = convertInterval(mMinSwapInterval);
    presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
    presentParameters.Windowed = TRUE;

    DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;

    HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);

    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
    {
        return error(EGL_BAD_ALLOC, false);
    }

    if (FAILED(result))
    {
        result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);

        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
        {
            return error(EGL_BAD_ALLOC, false);
        }
    }

    ASSERT(SUCCEEDED(result));

    // Permanent non-default states
    mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);

    mSceneStarted = false;

    return true;
}
Esempio n. 3
0
void Surface::setSwapInterval(EGLint interval)
{
    if (mSwapInterval == interval)
    {
        return;
    }
    
    mSwapInterval = interval;
    mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
    mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());

    mPresentInterval = convertInterval(mSwapInterval);
    mPresentIntervalDirty = true;
}
Esempio n. 4
0
EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
{
    IDirect3DDevice9 *device = mRenderer->getDevice();

    if (device == NULL)
    {
        return EGL_BAD_ACCESS;
    }

    // Evict all non-render target textures to system memory and release all resources
    // before reallocating them to free up as much video memory as possible.
    device->EvictManagedResources();

    HRESULT result;

    // Release specific resources to free up memory for the new render target, while the
    // old render target still exists for the purpose of preserving its contents.
    if (mSwapChain)
    {
        mSwapChain->Release();
        mSwapChain = NULL;
    }

    if (mBackBuffer)
    {
        mBackBuffer->Release();
        mBackBuffer = NULL;
    }

    if (mOffscreenTexture)
    {
        mOffscreenTexture->Release();
        mOffscreenTexture = NULL;
    }

    if (mDepthStencil)
    {
        mDepthStencil->Release();
        mDepthStencil = NULL;
    }

    HANDLE *pShareHandle = NULL;
    if (!mWindow && mRenderer->getShareHandleSupport())
    {
        pShareHandle = &mShareHandle;
    }

    result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
                                   gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT,
                                   &mOffscreenTexture, pShareHandle);
    if (FAILED(result))
    {
        ERR("Could not create offscreen texture: %08lX", result);
        release();

        if (d3d9::isDeviceLostError(result))
        {
            return EGL_CONTEXT_LOST;
        }
        else
        {
            return EGL_BAD_ALLOC;
        }
    }

    IDirect3DSurface9 *oldRenderTarget = mRenderTarget;

    result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
    ASSERT(SUCCEEDED(result));

    if (oldRenderTarget)
    {
        RECT rect =
        {
            0, 0,
            mWidth, mHeight
        };

        if (rect.right > static_cast<LONG>(backbufferWidth))
        {
            rect.right = backbufferWidth;
        }

        if (rect.bottom > static_cast<LONG>(backbufferHeight))
        {
            rect.bottom = backbufferHeight;
        }

        mRenderer->endScene();

        result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
        ASSERT(SUCCEEDED(result));

        oldRenderTarget->Release();
    }

    if (mWindow)
    {
        D3DPRESENT_PARAMETERS presentParameters = {0};
        presentParameters.AutoDepthStencilFormat = gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat);
        presentParameters.BackBufferCount = 1;
        presentParameters.BackBufferFormat = gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat);
        presentParameters.EnableAutoDepthStencil = FALSE;
        presentParameters.Flags = 0;
        presentParameters.hDeviceWindow = mWindow;
        presentParameters.MultiSampleQuality = 0;                  // FIXME: Unimplemented
        presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;   // FIXME: Unimplemented
        presentParameters.PresentationInterval = convertInterval(swapInterval);
        presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
        presentParameters.Windowed = TRUE;
        presentParameters.BackBufferWidth = backbufferWidth;
        presentParameters.BackBufferHeight = backbufferHeight;

        // http://crbug.com/140239
        // http://crbug.com/143434
        //
        // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width
        // when using the integrated Intel. This rounds the width up rather than down.
        //
        // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID
        // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur.
        if (mRenderer->getAdapterVendor() == VENDOR_ID_INTEL)
        {
            presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64;
        }

        result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);

        if (FAILED(result))
        {
            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);

            ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
            release();

            if (d3d9::isDeviceLostError(result))
            {
                return EGL_CONTEXT_LOST;
            }
            else
            {
                return EGL_BAD_ALLOC;
            }
        }

        result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
        ASSERT(SUCCEEDED(result));
        InvalidateRect(mWindow, NULL, FALSE);
    }

    if (mDepthBufferFormat != GL_NONE)
    {
        result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight,
                                                   gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat),
                                                   D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL);

        if (FAILED(result))
        {
            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);

            ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
            release();

            if (d3d9::isDeviceLostError(result))
            {
                return EGL_CONTEXT_LOST;
            }
            else
            {
                return EGL_BAD_ALLOC;
            }
        }
    }

    mWidth = backbufferWidth;
    mHeight = backbufferHeight;
    mSwapInterval = swapInterval;

    return EGL_SUCCESS;
}