blob: d6aa3af3ba46b790770aeabdd2482a0b621f80ce [file] [log] [blame]
/*
* Copyright (C) 2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <d3d9.h>
#include <wtf/Forward.h>
#include <wtf/Lock.h>
#include <wtf/Noncopyable.h>
struct IDirect3DDevice9;
struct IDirect3DPixelShader9;
struct IDirect3DSwapChain9;
struct IDirect3DTexture9;
struct IDirect3DVertexBuffer9;
typedef struct _CACFContext* CACFContextRef;
typedef struct _CARenderOGLContext CARenderOGLContext;
namespace WKQCA {
class Image;
class D3DPostProcessingContext {
WTF_MAKE_FAST_ALLOCATED;
public:
D3DPostProcessingContext(const CComPtr<IDirect3DTexture9>&, const CComPtr<IDirect3DVertexBuffer9>&);
IDirect3DTexture9* sceneTexture() const { return m_sceneTexture; }
IDirect3DVertexBuffer9* overlayQuad() const { return m_overlayQuad; }
private:
CComPtr<IDirect3DTexture9> m_sceneTexture;
CComPtr<IDirect3DVertexBuffer9> m_overlayQuad;
};
class CAD3DRenderer {
WTF_MAKE_NONCOPYABLE(CAD3DRenderer);
public:
static CAD3DRenderer& shared();
// Returns a swap chain that can be used to render into the given window. The swap chain's
// buffers' dimensions match the passed-in size. If necessary, this function will create or
// reset the D3D device.
CComPtr<IDirect3DSwapChain9> swapChain(CWindow, const CGSize&);
// Creates a context used by CAD3DRenderer to post-process the rendered scene.
// The only post-processing effect currently supported is color inversion.
// This method returns nullptr if no post-processing is to be applied.
std::unique_ptr<D3DPostProcessingContext> createD3DPostProcessingContext(IDirect3DSwapChain9*, const CGSize&);
enum RenderResult { DeviceBecameLost, DeviceIsLost, OtherFailure, NoRenderingRequired, Success };
// Call these functions to render the given context into the given swap chain's back buffer.
// renderAndPresent then presents the back buffer to the screen, while renderToImage copies the
// updated region to a system-memory Image. nextRenderTime is set to the CAMediaTime at which
// the context needs to be rendered again (or infinity, if no further rendering is required or
// the device has entered the lost state).
RenderResult renderAndPresent(const CGRect& bounds, IDirect3DSwapChain9*, D3DPostProcessingContext*, CACFContextRef, CFTimeInterval& nextRenderTime);
RenderResult renderToImage(const CGRect& bounds, IDirect3DSwapChain9*, D3DPostProcessingContext*, CACFContextRef, RefPtr<Image>&, CGPoint& imageOrigin, CFTimeInterval& nextRenderTime);
// Call this when the process is exiting to prevent the debug Direct3D runtime from reporting
// memory leaks. Calling it when the release Direct3D runtime is being used is harmless (other
// than some unknown performance cost).
void release();
CComPtr<IDirect3DDevice9> d3dDevice9() const { return m_d3dDevice; }
private:
CAD3DRenderer();
~CAD3DRenderer();
bool initialize(CWindow, const CGSize&);
RenderResult renderInternal(const CGRect& bounds, IDirect3DSwapChain9*, D3DPostProcessingContext*, CACFContextRef, CGRect& dirtyRect, CFTimeInterval& nextRenderTime);
void postProcess(const CGRect&, IDirect3DSwapChain9*, D3DPostProcessingContext*);
void setDeviceIsLost(bool);
bool resetD3DDevice(CWindow, const CGSize&);
void createShaderIfNeeded();
Lock m_lock;
CComPtr<IDirect3DDevice9> m_d3dDevice;
CARenderOGLContext* m_renderOGLContext { nullptr };
CComPtr<IDirect3DPixelShader9> m_pixelShader;
#if ASSERT_ENABLED
DWORD m_deviceThreadID { 0 };
#endif
bool m_initialized { false };
bool m_deviceIsLost { false };
bool m_invertsColors { false };
bool m_usingDirect3D9Ex { false };
};
} // namespace WKQCA