#pragma once
#include "CAD3DRenderer.h"
#include "CVDisplayLinkClient.h"
#include <wtf/RefCounted.h>
#include <wtf/RetainPtr.h>
typedef struct _CACFContext* CACFContextRef;
typedef struct _CACFLayer* CACFLayerRef;
namespace WKQCA {
class Image;
class CAView : public RefCounted<CAView>, private CVDisplayLinkClient {
public:
enum DrawingDestination {
DrawingDestinationWindow,
DrawingDestinationImage,
};
class Handle;
static RefPtr<CAView> create(DrawingDestination);
~CAView();
typedef void (*ContextDidChangeCallbackFunction)(CAView*, void* info);
void setContextDidChangeCallback(ContextDidChangeCallbackFunction, void* info);
CACFContextRef context() const { return m_context.get(); }
void setLayer(CACFLayerRef);
void update(CWindow, const CGRect& bounds);
void invalidateRects(const CGRect*, size_t count);
bool canDraw() const { return m_swapChain; }
void drawToWindow();
RefPtr<Image> drawToImage(CGPoint& imageLocation, CFTimeInterval& nextDrawTime);
void drawIntoDC(HDC);
void setShouldInvertColors(bool);
IDirect3DDevice9* d3dDevice9();
private:
struct ContextDidChangeCallback {
ContextDidChangeCallback()
: function(0), info(0) { }
ContextDidChangeCallbackFunction function;
void* info;
};
CAView(DrawingDestination);
void drawToWindowInternal();
bool willDraw(bool& willUpdateSoon);
void didDraw(CAD3DRenderer::RenderResult, bool& willUpdateSoon);
void scheduleNextDraw(CFTimeInterval mediaTime);
static void contextDidChangeCallback(void*, void* info, void*);
void contextDidChange();
static void releaseAllD3DResources();
void updateSoon();
static void CALLBACK updateViewsNow(HWND, UINT, UINT_PTR, DWORD);
virtual void displayLinkReachedCAMediaTime(CVDisplayLink*, CFTimeInterval);
DrawingDestination m_destination;
Ref<Handle> m_handle;
RetainPtr<CACFLayerRef> m_layer;
ContextDidChangeCallback m_contextDidChangeCallback;
Lock m_lock;
RetainPtr<CACFContextRef> m_context;
CWindow m_window;
CGRect m_bounds { CGRectZero };
CComPtr<IDirect3DSwapChain9> m_swapChain;
std::unique_ptr<D3DPostProcessingContext> m_d3dPostProcessingContext;
Lock m_displayLinkLock;
RefPtr<CVDisplayLink> m_displayLink;
CFTimeInterval m_nextDrawTime { 0 };
bool m_drawingProhibited { false };
bool m_shouldInvertColors { false };
bool m_flushing { false };
};
}