/* * 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 { 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_DISABLED DWORD m_deviceThreadID { 0 }; #endif bool m_initialized { false }; bool m_deviceIsLost { false }; bool m_invertsColors { false }; bool m_usingDirect3D9Ex { false }; }; } // namespace WKQCA