📄 qpaintengine_d3d.cpp
字号:
}static int qd3d_cache_limit = 64*1024; // cache ~64 MB worth of texturestypedef QCache<quint64, QD3DImage> QD3DImageCache;class QD3DImageManager{public: QD3DImageManager() { // ### GL does the same! qt_image_cleanup_hook_64 = qd3d_image_cleanup; cache.setMaxCost(qd3d_cache_limit); } ~QD3DImageManager() {// qDebug() << "unhooking d3d image cache"; qt_image_cleanup_hook_64 = 0; cache.clear(); } IDirect3DTexture9 *lookup(IDirect3DDevice9 *device, const QImage &image); void remove(quint64 key);private: QD3DImageCache cache;};IDirect3DTexture9 *QD3DImageManager::lookup(IDirect3DDevice9 *device, const QImage &image){ QD3DImage *tex_image = 0; tex_image = cache.object(image.cacheKey()); if (!tex_image) { // to avoid cache thrashing we remove images from the cache // that have the same serial no as the cached image, since // that image is most likely destoyed already, and we got a // stale cache entry uint serial = (uint) (image.cacheKey() >> 32); QList<quint64> keys = cache.keys(); for (int i=0; i<keys.size(); ++i) { if ((uint)(keys.at(i) >> 32) == serial) { cache.remove(keys.at(i)); break; } }// qDebug(" => cached: %d, adding cache image: 0x%08x%08x",cache.size(), uint (image.cacheKey() >> 32),uint (image.cacheKey() & 0xffffffff)); // add cache entry int cost = image.width()*image.height()*4/1024; if (cache.totalCost() + cost > cache.maxCost()) { // no room for new entries? kick out half the cached images int old_max_cost = cache.maxCost(); cache.setMaxCost(old_max_cost/2); cache.setMaxCost(old_max_cost); } tex_image = new QD3DImage(device, image); cache.insert(image.cacheKey(), tex_image, cost);// qDebug() << "==> total cache cost: " << cache.totalCost() << cost; } return tex_image->texture;}void QD3DImageManager::remove(quint64 key){// QList<quint64> keys = cache.keys();// if (keys.contains(key))// qDebug() << "entery removed from cache"; cache.remove(key);}Q_GLOBAL_STATIC(QD3DImageManager, qd3d_image_cache)static void qd3d_image_cleanup(qint64 key){// qDebug() << "qd3d_image_cleanup:";// qDebug(" => key: 0x%08x%08x", (uint) (key >> 32), (uint)(key & 0xffffffff)); qd3d_image_cache()->remove(key);}//// end D3D image cache stuff//class QD3DDrawHelper : public QTessellator{public: QD3DDrawHelper(QDirect3DPaintEnginePrivate *pe); ~QD3DDrawHelper(); bool needsFlushing() const; QD3DMaskPosition allocateMaskPosition(const QRectF &brect, bool *breakbatch); void setClipPath(const QPainterPath &path, QD3DBatchItem **item); void queueAntialiasedMask(const QPolygonF &poly, QD3DBatchItem **item, const QRectF &brect); QRectF queueAliasedMask(const QPainterPath &path, QD3DBatchItem **item, D3DCOLOR color); void queueRect(const QRectF &rect, QD3DBatchItem *item, D3DCOLOR color, const QPolygonF &trect); void queueRect(const QRectF &rect, QD3DBatchItem *item, D3DCOLOR color); void queueTextGlyph(const QRectF &rect, const qreal *tex_coords, QD3DBatchItem *item, D3DCOLOR color); void queueAntialiasedLines(const QPainterPath &path, QD3DBatchItem **item, const QRectF &brect); void queueAliasedLines(const QLineF *lines, int lineCount, QD3DBatchItem **item); int drawAntialiasedMask(int offset, int maxoffset); void drawAliasedMask(int offset); void drawAntialiasedBoundingRect(QD3DBatchItem *item); void drawAliasedBoundingRect(QD3DBatchItem *item); void drawTextItem(QD3DBatchItem *item); void drawAliasedLines(QD3DBatchItem *item); void setMaskSize(QSize size); void beforeReset(); void afterReset(); IDirect3DSurface9 *freeMaskSurface(); inline void lockVertexBuffer(); inline void unlockVertexBuffer(); inline int index() { return m_index; }#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS enum VertexBufferAccess { CLEAR = 0x00, READ = 0x01, WRITE = 0x02 }; int accesscontrol[QT_VERTEX_BUF_SIZE];#endifprivate: void addTrap(const Trapezoid &trap); void tessellate(const QPolygonF &poly); inline void lineToStencil(qreal x, qreal y); inline void curveToStencil(const QPointF &cp1, const QPointF &cp2, const QPointF &ep); QRectF pathToVertexArrays(const QPainterPath &path); void resetMask(); QDirect3DPaintEnginePrivate *m_pe; qreal m_xoffset, m_yoffset; int m_startindex; int m_index; int m_height, m_width; LPDIRECT3DVERTEXBUFFER9 m_d3dvbuff; vertex *m_vbuff; QD3DBatchItem *m_item; QRectF m_boundingRect; qreal max_x; qreal max_y; qreal min_x; qreal min_y; qreal firstx; qreal firsty; QPointF tess_lastpoint; int tess_index; bool m_locked; IDirect3DTexture9 *m_mask; IDirect3DSurface9 *m_maskSurface; IDirect3DSurface9 *m_depthStencilSurface; D3DCOLOR m_color; bool m_clearmask; bool m_isLine; bool m_firstPoint; QD3DMaskPosition m_mask_position; int m_mask_offsetX2; int m_mask_offsetY2;};QD3DStateManager::QD3DStateManager(LPDIRECT3DDEVICE9 pDevice, ID3DXEffect *effect) : m_pDevice(pDevice), m_effect(effect), m_refs(0){ if (FAILED(D3DXMatrixIdentity(&m_d3dIdentityMatrix))) { qWarning("QDirect3DPaintEngine: D3DXMatrixIdentity failed"); } reset();}void QD3DStateManager::reset(){ m_radgradfd = -1; m_cosmetic_pen = false; m_pass = -1; m_maskchannel = -1; m_brushmode = -1; m_texture = 0; m_xoffset = INT_MAX; m_yoffset = INT_MAX; m_vertexshader = 0; m_pixelshader = 0; m_isIdentity = true; m_transformation = QTransform(); m_effect->SetMatrix("g_mTransformation", &m_d3dIdentityMatrix); ZeroMemory(&m_projection, sizeof(D3DMATRIX)); ZeroMemory(m_textures, sizeof(LPDIRECT3DBASETEXTURE9) * D3D_STAGE_COUNT); FillMemory(m_samplerstates, sizeof(DWORD) * D3D_SAMPLE_STATES * D3D_STAGE_COUNT, 0xFFFFFFFE); FillMemory(m_texturestates, sizeof(DWORD) * D3D_TEXTURE_STATES * D3D_STAGE_COUNT, 0xFFFFFFFE); FillMemory(m_renderstate, sizeof(DWORD) * D3D_RENDER_STATES, 0xFFFFFFFE);}inline void QD3DStateManager::beginPass(int pass){ if (pass != m_pass) { if (m_pass != -1) m_effect->EndPass(); m_effect->BeginPass(pass); m_pass = pass; }}inline void QD3DStateManager::endPass(){ if (m_pass != -1) { m_pass = -1; m_effect->EndPass(); }}inline void QD3DStateManager::startStateBlock() { m_changed = false;}inline void QD3DStateManager::setCosmeticPen(bool enabled){ if (enabled != m_cosmetic_pen) { m_effect->SetBool("g_mCosmeticPen", enabled); m_cosmetic_pen = enabled; m_changed = true; }}inline void QD3DStateManager::setBrushMode(int mode){ if (mode != m_brushmode) { m_effect->SetInt("g_mBrushMode", mode); m_brushmode = mode; m_changed = true; }}inline void QD3DStateManager::setTexture(LPDIRECT3DBASETEXTURE9 pTexture){ SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); if (pTexture != m_texture) { m_texture = pTexture; m_effect->SetTexture("g_mTexture", pTexture); m_changed = true; }}inline void QD3DStateManager::setTexture(LPDIRECT3DBASETEXTURE9 pTexture, QGradient::Spread spread){ switch(spread) { case QGradient::RepeatSpread: SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); break; case QGradient::ReflectSpread: SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR); SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR); break; default: SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); break; }; if (pTexture != m_texture) { m_texture = pTexture; m_effect->SetTexture("g_mTexture", pTexture); m_changed = true; }}inline void QD3DStateManager::setTransformation(const QTransform *matrix){ if (matrix) { if (*matrix != m_transformation) { D3DXMATRIX dxmatrix(matrix->m11(), matrix->m12(), 0, matrix->m13(), matrix->m21(), matrix->m22(), 0, matrix->m23(), 0, 0, 1, 0, matrix->dx(), matrix->dy(), 0, 1); m_effect->SetMatrix("g_mTransformation", &dxmatrix); m_transformation = *matrix; m_changed = true; m_isIdentity = false; } } else if (!m_isIdentity) { m_effect->SetMatrix("g_mTransformation", &m_d3dIdentityMatrix); m_transformation = QTransform(); m_changed = true; m_isIdentity = true; }}inline void QD3DStateManager::setProjection(const D3DXMATRIX *pMatrix){ if (*pMatrix != m_projection) { m_effect->SetMatrix("g_mViewProjection", pMatrix); m_projection = *pMatrix; m_changed = true; }}inline void QD3DStateManager::setFocalDistance(const qreal &fd){ if (fd != m_radgradfd) { m_effect->SetFloat("g_mFocalDist", fd); m_changed = true; m_radgradfd = fd; }}inline void QD3DStateManager::setMaskOffset(qreal x, qreal y){ if (x != m_xoffset || y != m_yoffset) { float offset[2] = {x, y}; m_effect->SetFloatArray("g_mMaskOffset", offset, 2); m_xoffset = x; m_yoffset = y; m_changed = true; }}inline void QD3DStateManager::setMaskChannel(int channel){ if (m_maskchannel != channel) { m_effect->SetIntArray("g_mChannel", m_mask_channels[channel], 4); m_maskchannel = channel; m_changed = true; }}inline void QD3DStateManager::endStateBlock(){ if (m_changed) { m_effect->CommitChanges(); m_changed = false; }}STDMETHODIMP QD3DStateManager::QueryInterface(REFIID iid, LPVOID *ppv){ if(iid == IID_IUnknown || iid == IID_ID3DXEffectStateManager) { *ppv = this; ++m_refs; return NOERROR; } *ppv = NULL; return ResultFromScode(E_NOINTERFACE);}STDMETHODIMP_(ULONG) QD3DStateManager::AddRef(void){ return (ULONG)InterlockedIncrement( &m_refs );}STDMETHODIMP_(ULONG) QD3DStateManager::Release(void){ if( 0L == InterlockedDecrement( &m_refs ) ) { delete this; return 0L; } return m_refs;}STDMETHODIMP QD3DStateManager::SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix){ return m_pDevice->SetTransform(State, pMatrix);}STDMETHODIMP QD3DStateManager::SetMaterial(CONST D3DMATERIAL9 *pMaterial){ return m_pDevice->SetMaterial(pMaterial);}STDMETHODIMP QD3DStateManager::SetLight(DWORD Index, CONST D3DLIGHT9 *pLight){ return m_pDevice->SetLight(Index, pLight);}STDMETHODIMP QD3DStateManager::LightEnable(DWORD Index, BOOL Enable){ return m_pDevice->LightEnable(Index, Enable);}STDMETHODIMP QD3DStateManager::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value){ if (State < D3D_RENDER_STATES) { if (m_renderstate[State] == Value) return S_OK; m_renderstate[State] = Value; } return m_pDevice->SetRenderState(State, Value);}STDMETHODIMP QD3DStateManager::SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture){ if (Stage < D3D_STAGE_COUNT) { if (m_textures[Stage] == pTexture) return S_OK; m_textures[Stage] = pTexture; } return m_pDevice->SetTexture(Stage, pTexture);}STDMETHODIMP QD3DStateManager::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value){ if (Stage < D3D_STAGE_COUNT && Type < D3D_TEXTURE_STATES) { if (m_texturestates[Stage][Type] == Value) return S_OK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -