michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef GFX_LAYERMANAGERD3D10_H michael@0: #define GFX_LAYERMANAGERD3D10_H michael@0: michael@0: #include "Layers.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "gfxContext.h" michael@0: #include "mozilla/gfx/UserData.h" michael@0: #include "nsIWidget.h" michael@0: michael@0: #include "ReadbackManagerD3D10.h" michael@0: michael@0: namespace mozilla { michael@0: namespace layers { michael@0: michael@0: class DummyRoot; michael@0: class Nv3DVUtils; michael@0: michael@0: /** michael@0: * This structure is used to pass rectangles to our shader constant. We can use michael@0: * this for passing rectangular areas to SetVertexShaderConstant. In the format michael@0: * of a 4 component float(x,y,width,height). Our vertex shader can then use michael@0: * this to construct rectangular positions from the 0,0-1,1 quad that we source michael@0: * it with. michael@0: */ michael@0: struct ShaderConstantRectD3D10 michael@0: { michael@0: float mX, mY, mWidth, mHeight; michael@0: ShaderConstantRectD3D10(float aX, float aY, float aWidth, float aHeight) michael@0: : mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight) michael@0: { } michael@0: michael@0: // For easy passing to SetVertexShaderConstantF. michael@0: operator float* () { return &mX; } michael@0: }; michael@0: michael@0: /* michael@0: * This is the LayerManager used for Direct3D 10. For now this will michael@0: * render on the main thread. michael@0: * michael@0: * For the time being, LayerManagerD3D10 forwards layers michael@0: * transactions. michael@0: */ michael@0: class LayerManagerD3D10 : public LayerManager { michael@0: typedef mozilla::gfx::DrawTarget DrawTarget; michael@0: typedef mozilla::gfx::IntSize IntSize; michael@0: typedef mozilla::gfx::SurfaceFormat SurfaceFormat; michael@0: michael@0: public: michael@0: LayerManagerD3D10(nsIWidget *aWidget); michael@0: virtual ~LayerManagerD3D10(); michael@0: michael@0: /* michael@0: * Initializes the layer manager, this is when the layer manager will michael@0: * actually access the device and attempt to create the swap chain used michael@0: * to draw to the window. If this method fails the device cannot be used. michael@0: * This function is not threadsafe. michael@0: * michael@0: * return True is initialization was succesful, false when it was not. michael@0: */ michael@0: bool Initialize(bool force = false, HRESULT* aHresultPtr = nullptr); michael@0: michael@0: /* michael@0: * LayerManager implementation. michael@0: */ michael@0: virtual void Destroy(); michael@0: michael@0: virtual void SetRoot(Layer *aLayer); michael@0: michael@0: virtual void BeginTransaction(); michael@0: michael@0: virtual void BeginTransactionWithTarget(gfxContext* aTarget); michael@0: michael@0: virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT); michael@0: michael@0: struct CallbackInfo { michael@0: DrawThebesLayerCallback Callback; michael@0: void *CallbackData; michael@0: }; michael@0: michael@0: virtual void EndTransaction(DrawThebesLayerCallback aCallback, michael@0: void* aCallbackData, michael@0: EndTransactionFlags aFlags = END_DEFAULT); michael@0: michael@0: const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; } michael@0: michael@0: // D3D10 guarantees textures can be at least this size michael@0: enum { michael@0: MAX_TEXTURE_SIZE = 8192 michael@0: }; michael@0: virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) michael@0: { michael@0: return aSize <= gfx::IntSize(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE); michael@0: } michael@0: michael@0: virtual int32_t GetMaxTextureSize() const michael@0: { michael@0: return MAX_TEXTURE_SIZE; michael@0: } michael@0: michael@0: virtual already_AddRefed CreateThebesLayer(); michael@0: virtual already_AddRefed CreateContainerLayer(); michael@0: virtual already_AddRefed CreateImageLayer(); michael@0: virtual already_AddRefed CreateColorLayer(); michael@0: virtual already_AddRefed CreateCanvasLayer(); michael@0: virtual already_AddRefed CreateReadbackLayer(); michael@0: michael@0: virtual TemporaryRef michael@0: CreateOptimalDrawTarget(const IntSize &aSize, michael@0: SurfaceFormat aSurfaceFormat); michael@0: michael@0: virtual TemporaryRef michael@0: CreateOptimalMaskDrawTarget(const IntSize &aSize); michael@0: michael@0: virtual TemporaryRef michael@0: CreateDrawTarget(const gfx::IntSize &aSize, michael@0: mozilla::gfx::SurfaceFormat aFormat); michael@0: michael@0: virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_D3D10; } michael@0: virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 10"); } michael@0: michael@0: virtual const char* Name() const { return "D3D10"; } michael@0: michael@0: // Public helpers michael@0: michael@0: ID3D10Device1 *device() const { return mDevice; } michael@0: michael@0: ID3D10Effect *effect() const { return mEffect; } michael@0: IDXGISwapChain *SwapChain() const michael@0: { michael@0: return mSwapChain; michael@0: } michael@0: ReadbackManagerD3D10 *readbackManager(); michael@0: michael@0: void SetupInputAssembler(); michael@0: void SetViewport(const nsIntSize &aViewport); michael@0: const nsIntSize &GetViewport() { return mViewport; } michael@0: michael@0: /** michael@0: * Return pointer to the Nv3DVUtils instance michael@0: */ michael@0: Nv3DVUtils *GetNv3DVUtils() { return mNv3DVUtils; } michael@0: michael@0: static void ReportFailure(const nsACString &aMsg, HRESULT aCode); michael@0: michael@0: private: michael@0: void SetupPipeline(); michael@0: void UpdateRenderTarget(); michael@0: void VerifyBufferSize(); michael@0: void EnsureReadbackManager(); michael@0: michael@0: void Render(EndTransactionFlags aFlags); michael@0: michael@0: nsRefPtr mDevice; michael@0: michael@0: nsRefPtr mEffect; michael@0: nsRefPtr mInputLayout; michael@0: nsRefPtr mVertexBuffer; michael@0: nsRefPtr mReadbackManager; michael@0: michael@0: nsRefPtr mRTView; michael@0: michael@0: nsRefPtr mSwapChain; michael@0: michael@0: nsIWidget *mWidget; michael@0: michael@0: bool mDisableSequenceForNextFrame; michael@0: michael@0: CallbackInfo mCurrentCallbackInfo; michael@0: michael@0: nsIntSize mViewport; michael@0: michael@0: /* Nv3DVUtils instance */ michael@0: nsAutoPtr mNv3DVUtils; michael@0: michael@0: /* michael@0: * Context target, nullptr when drawing directly to our swap chain. michael@0: */ michael@0: nsRefPtr mTarget; michael@0: michael@0: /* michael@0: * Copies the content of our backbuffer to the set transaction target. michael@0: */ michael@0: void PaintToTarget(); michael@0: }; michael@0: michael@0: /* michael@0: * General information and tree management for OGL layers. michael@0: */ michael@0: class LayerD3D10 michael@0: { michael@0: public: michael@0: LayerD3D10(LayerManagerD3D10 *aManager); michael@0: michael@0: virtual LayerD3D10 *GetFirstChildD3D10() { return nullptr; } michael@0: michael@0: void SetFirstChild(LayerD3D10 *aParent); michael@0: michael@0: virtual Layer* GetLayer() = 0; michael@0: michael@0: /** michael@0: * This will render a child layer to whatever render target is currently michael@0: * active. michael@0: */ michael@0: virtual void RenderLayer() = 0; michael@0: virtual void Validate() {} michael@0: michael@0: ID3D10Device1 *device() const { return mD3DManager->device(); } michael@0: ID3D10Effect *effect() const { return mD3DManager->effect(); } michael@0: michael@0: /* Called by the layer manager when it's destroyed */ michael@0: virtual void LayerManagerDestroyed() {} michael@0: michael@0: /** michael@0: * Return pointer to the Nv3DVUtils instance. Calls equivalent method in LayerManager. michael@0: */ michael@0: Nv3DVUtils *GetNv3DVUtils() { return mD3DManager->GetNv3DVUtils(); } michael@0: michael@0: /* michael@0: * Returns a shader resource view of a texture containing the contents of this michael@0: * layer. Will try to return an existing texture if possible, or a temporary michael@0: * one if not. It is the callee's responsibility to release the shader michael@0: * resource view. Will return null if a texture could not be constructed. michael@0: * The texture will not be transformed, i.e., it will be in the same coord michael@0: * space as this. michael@0: * Any layer that can be used as a mask layer should override this method. michael@0: * If aSize is non-null, it will contain the size of the texture. michael@0: */ michael@0: virtual already_AddRefed GetAsTexture(gfx::IntSize* aSize) michael@0: { michael@0: return nullptr; michael@0: } michael@0: michael@0: void SetEffectTransformAndOpacity() michael@0: { michael@0: Layer* layer = GetLayer(); michael@0: const gfx::Matrix4x4& transform = layer->GetEffectiveTransform(); michael@0: void* raw = &const_cast(transform)._11; michael@0: effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64); michael@0: effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(layer->GetEffectiveOpacity()); michael@0: } michael@0: michael@0: protected: michael@0: /* michael@0: * Finds a texture for this layer's mask layer (if it has one) and sets it michael@0: * as an input to the shaders. michael@0: * Returns SHADER_MASK if a texture is loaded, SHADER_NO_MASK if there was no michael@0: * mask layer, or a texture for the mask layer could not be loaded. michael@0: */ michael@0: uint8_t LoadMaskTexture(); michael@0: michael@0: /** michael@0: * Select a shader technique using a combination of the following flags. michael@0: * Not all combinations of flags are supported, and might cause an error, michael@0: * check the fx file to see which shaders exist. In particular, aFlags should michael@0: * include any combination of the 0x20 bit = 0 flags OR one of the 0x20 bit = 1 michael@0: * flags. Mask flags can be used in either case. michael@0: */ michael@0: ID3D10EffectTechnique* SelectShader(uint8_t aFlags); michael@0: const static uint8_t SHADER_NO_MASK = 0; michael@0: const static uint8_t SHADER_MASK = 0x1; michael@0: const static uint8_t SHADER_MASK_3D = 0x2; michael@0: // 0x20 bit = 0 michael@0: const static uint8_t SHADER_RGB = 0; michael@0: const static uint8_t SHADER_RGBA = 0x4; michael@0: const static uint8_t SHADER_NON_PREMUL = 0; michael@0: const static uint8_t SHADER_PREMUL = 0x8; michael@0: const static uint8_t SHADER_LINEAR = 0; michael@0: const static uint8_t SHADER_POINT = 0x10; michael@0: // 0x20 bit = 1 michael@0: const static uint8_t SHADER_YCBCR = 0x20; michael@0: const static uint8_t SHADER_COMPONENT_ALPHA = 0x24; michael@0: const static uint8_t SHADER_SOLID = 0x28; michael@0: michael@0: LayerManagerD3D10 *mD3DManager; michael@0: }; michael@0: michael@0: } /* layers */ michael@0: } /* mozilla */ michael@0: michael@0: #endif /* GFX_LAYERMANAGERD3D9_H */