diff --git a/gfx/doc/AdvancedLayers.md b/gfx/doc/AdvancedLayers.md deleted file mode 100644 index d813a306b623..000000000000 --- a/gfx/doc/AdvancedLayers.md +++ /dev/null @@ -1,313 +0,0 @@ -Advanced Layers -============== - -Advanced Layers is a new method of compositing layers in Gecko. This document serves as a technical -overview and provides a short walk-through of its source code. - -Overview -------------- - -Advanced Layers attempts to group as many GPU operations as it can into a single draw call. This is -a common technique in GPU-based rendering called "batching". It is not always trivial, as a -batching algorithm can easily waste precious CPU resources trying to build optimal draw calls. - -Advanced Layers reuses the existing Gecko layers system as much as possible. Huge layer trees do -not currently scale well (see the future work section), so opportunities for batching are currently -limited without expending unnecessary resources elsewhere. However, Advanced Layers has a few -benefits: - - * It submits smaller GPU workloads and buffer uploads than the existing compositor. - * It needs only a single pass over the layer tree. - * It uses occlusion information more intelligently. - * It is easier to add new specialized rendering paths and new layer types. - * It separates compositing logic from device logic, unlike the existing compositor. - * It is much faster at rendering 3d scenes or complex layer trees. - * It has experimental code to use the z-buffer for occlusion culling. - -Because of these benefits we hope that it provides a significant improvement over the existing -compositor. - -Advanced Layers uses the acronym "MLG" and "MLGPU" in many places. This stands for "Mid-Level -Graphics", the idea being that it is optimized for Direct3D 11-style rendering systems as opposed -to Direct3D 12 or Vulkan. - -LayerManagerMLGPU ------------------------------- - -Advanced layers does not change client-side rendering at all. Content still uses Direct2D (when -possible), and creates identical layer trees as it would with a normal Direct3D 11 compositor. In -fact, Advanced Layers re-uses all of the existing texture handling and video infrastructure as -well, replacing only the composite-side layer types. - -Advanced Layers does not create a `LayerManagerComposite` - instead, it creates a -`LayerManagerMLGPU`. This layer manager does not have a `Compositor` - instead, it has an -`MLGDevice`, which roughly abstracts the Direct3D 11 API. (The hope is that this API is easily -interchangeable for something else when cross-platform or software support is needed.) - -`LayerManagerMLGPU` also dispenses with the old "composite" layers for new layer types. For -example, `ColorLayerComposite` becomes `ColorLayerMLGPU`. Since these layer types implement -`HostLayer`, they integrate with `LayerTransactionParent` as normal composite layers would. - -Rendering Overview ----------------------------- - -The steps for rendering are described in more detail below, but roughly the process is: - -1. Sort layers front-to-back. -2. Create a dependency tree of render targets (called "views"). -3. Accumulate draw calls for all layers in each view. -4. Upload draw call buffers to the GPU. -5. Execute draw commands for each view. - -Advanced Layers divides the layer tree into "views" (`RenderViewMLGPU`), which correspond to a -render target. The root layer is represented by a view corresponding to the screen. Layers that -require intermediate surfaces have temporary views. Layers are analyzed front-to-back, and rendered -back-to-front within a view. Views themselves are rendered front-to-back, to minimize render target -switching. - -Each view contains one or more rendering passes (`RenderPassMLGPU`). A pass represents a single -draw command with one or more rendering items attached to it. For example, a `SolidColorPass` item -contains a rectangle and an RGBA value, and many of these can be drawn with a single GPU call. - -When considering a layer, views will first try to find an existing rendering batch that can support -it. If so, that pass will accumulate another draw item for the layer. Otherwise, a new pass will be -added. - -When trying to find a matching pass for a layer, there is a tradeoff in CPU time versus the GPU -time saved by not issuing another draw commands. We generally care more about CPU time, so we do -not try too hard in matching items to an existing batch. - -After all layers have been processed, there is a "prepare" step. This copies all accumulated draw -data and uploads it into vertex and constant buffers in the GPU. - -Finally, we execute rendering commands. At the end of the frame, all batches and (most) constant -buffers are thrown away. - -Shaders Overview -------------------------------------- - -Advanced Layers currently has five layer-related shader pipelines: - - - Textured (PaintedLayer, ImageLayer, CanvasLayer) - - ComponentAlpha (PaintedLayer with component-alpha) - - YCbCr (ImageLayer with YCbCr video) - - Color (ColorLayers) - - Blend (ContainerLayers with mix-blend modes) - -There are also three special shader pipelines: - - MaskCombiner, which is used to combine mask layers into a single texture. - - Clear, which is used for fast region-based clears when not directly supported by the GPU. - - Diagnostic, which is used to display the diagnostic overlay texture. - -The basic layer shaders follow a unified structure. Each pipeline has a vertex and pixel shader. -The vertex shader takes a layers ID, a z-buffer depth, a vertex (in a triangle list), and any -ancillary data needed for the pixel shader. Often this ancillary data is just an index into -a constant buffer (more on this below). - -The vertex shader applies transforms and sends data down to the pixel shader, which performs -clipping and masking. - -Most of the time, layers have simple rectangular clips with simple rectilinear transforms, and -pixel shaders do not need to perform masking or clipping. We take advantage of this for common -layer types, and use a second set of vertex and pixel shaders. These shaders have a unified -input layout: a draw rect, a layers ID, and a z-buffer depth. The pipeline uses a unit quad -as input. Ancillary data is stored in a constant buffer, which is indexed by the instance ID. -This path performs clipping in the vertex shader, and the pixel shader does not support masks. - -Most shader types use ancillary data (such as texture coordinates, or a color value). This is -stored in a constant buffer, which is bound to the vertex shader. Unit quad shaders use -instancing to access the buffer. Full-fledged, triangle list shaders store the index in each -vertex. - -All of the shader-specific data is modelled in ShaderDefinitionsMLGPU.h. - -CPU Occlusion Culling -------------------------------------- - -By default, Advanced Layers performs occlusion culling on the CPU. Since layers are visited -front-to-back, this is simply a matter of accumulating the visible region of opaque layers, and -subtracting it from the visible region of subsequent layers. There is a major difference -between this occlusion culling and PostProcessLayers of the old compositor: AL performs culling -after invalidation, not before. Completely valid layers will have an empty visible region. - -Most layer types (with the exception of images) will intelligently split their draw calls into a -batch of individual rectangles, based on their visible region. - -Z-Buffering and Occlusion -------------------------------------- - -Advanced Layers also supports occlusion culling on the GPU, using a z-buffer. This is disabled by -default currently since it is significantly costly on integrated GPUs. When using the z-buffer, we -separate opaque layers into a separate list of passes. The render process then uses the following -steps: - - 1. The depth buffer is set to read-write. - 2. Opaque batches are executed., - 3. The depth buffer is set to read-only. - 4. Transparent batches are executed. - -The problem we have observed is that the depth buffer increases writes to the GPU, and on -integrated GPUs this is expensive - we have seen draw call times increase by 20-30%, which is the -wrong direction we want to take on battery life. In particular on a full screen video, the call to -ClearDepthStencilView plus the actual depth buffer write of the video can double GPU time. - -For now the depth-buffer is disabled until we can find a compelling case for it on non-integrated -hardware. - -Clipping -------------------------------------- - -Clipping is a bit tricky in Advanced Layers. We cannot use the hardware "scissor" feature, since the -clip can change from instance to instance within a batch. And if using the depth buffer, we -cannot write transparent pixels for the clipped area. As a result we always clip opaque draw rects -in the vertex shader (and sometimes even on the CPU, as is needed for sane texture coordiantes). -Only transparent items are clipped in the pixel shader. As a result, masked layers and layers with -non-rectangular transforms are always considered transparent, and use a more flexible clipping -pipeline. - -Plane Splitting ---------------------- - -Plane splitting is when a 3D transform causes a layer to be split - for example, one transparent -layer may intersect another on a separate plane. When this happens, Gecko sorts layers using a BSP -tree and produces a list of triangles instead of draw rects. - -These layers cannot use the "unit quad" shaders that support the fast clipping pipeline. Instead -they always use the full triangle-list shaders that support extended vertices and clipping. - -This is the slowest path we can take when building a draw call, since we must interact with the -polygon clipping and texturing code. - -Masks ---------- - -For each layer with a mask attached, Advanced Layers builds a `MaskOperation`. These operations -must resolve to a single mask texture, as well as a rectangular area to which the mask applies. All -batched pixel shaders will automatically clip pixels to the mask if a mask texture is bound. (Note -that we must use separate batches if the mask texture changes.) - -Some layers have multiple mask textures. In this case, the MaskOperation will store the list of -masks, and right before rendering, it will invoke a shader to combine these masks into a single texture. - -MaskOperations are shared across layers when possible, but are not cached across frames. - -BigImage Support --------------------------- - -ImageLayers and CanvasLayers can be tiled with many individual textures. This happens in rare cases -where the underlying buffer is too big for the GPU. Early on this caused problems for Advanced -Layers, since AL required one texture per layer. We implemented BigImage support by creating -temporary ImageLayers for each visible tile, and throwing those layers away at the end of the -frame. - -Advanced Layers no longer has a 1:1 layer:texture restriction, but we retain the temporary layer -solution anyway. It is not much code and it means we do not have to split `TexturedLayerMLGPU` -methods into iterated and non-iterated versions. - -Texture Locking ----------------------- - -Advanced Layers has a different texture locking scheme than the existing compositor. If a texture -needs to be locked, then it is locked by the MLGDevice automatically when bound to the current -pipeline. The MLGDevice keeps a set of the locked textures to avoid double-locking. At the end of -the frame, any textures in the locked set are unlocked. - -We cannot easily replicate the locking scheme in the old compositor, since the duration of using -the texture is not scoped to when we visit the layer. - -Buffer Measurements -------------------------------- - -Advanced Layers uses constant buffers to send layer information and extended instance data to the -GPU. We do this by pre-allocating large constant buffers and mapping them with `MAP_DISCARD` at the -beginning of the frame. Batches may allocate into this up to the maximum bindable constant buffer -size of the device (currently, 64KB). - -There are some downsides to this approach. Constant buffers are difficult to work with - they have -specific alignment requirements, and care must be taken not too run over the maximum number of -constants in a buffer. Another approach would be to store constants in a 2D texture and use vertex -shader texture fetches. Advanced Layers implemented this and benchmarked it to decide which -approach to use. Textures seemed to skew better on GPU performance, but worse on CPU, but this -varied depending on the GPU. Overall constant buffers performed best and most consistently, so we -have kept them. - -Additionally, we tested different ways of performing buffer uploads. Buffer creation itself is -costly, especially on integrated GPUs, and especially so for immutable, immediate-upload buffers. -As a result we aggressively cache buffer objects and always allocate them as MAP_DISCARD unless -they are write-once and long-lived. - -Buffer Types ------------- - -Advanced Layers has a few different classes to help build and upload buffers to the GPU. They are: - - - `MLGBuffer`. This is the low-level shader resource that `MLGDevice` exposes. It is the building - block for buffer helper classes, but it can also be used to make one-off, immutable, - immediate-upload buffers. MLGBuffers, being a GPU resource, are reference counted. - - `SharedBufferMLGPU`. These are large, pre-allocated buffers that are read-only on the GPU and - write-only on the CPU. They usually exceed the maximum bindable buffer size. There are three - shared buffers created by default and they are automatically unmapped as needed: one for vertices, - one for vertex shader constants, and one for pixel shader constants. When callers allocate into a - shared buffer they get back a mapped pointer, a GPU resource, and an offset. When the underlying - device supports offsetable buffers (like `ID3D11DeviceContext1` does), this results in better GPU - utilization, as there are less resources and fewer upload commands. - - `ConstantBufferSection` and `VertexBufferSection`. These are "views" into a `SharedBufferMLGPU`. - They contain the underlying `MLGBuffer`, and when offsetting is supported, the offset - information necessary for resource binding. Sections are not reference counted. - - `StagingBuffer`. A dynamically sized CPU buffer where items can be appended in a free-form - manner. The stride of a single "item" is computed by the first item written, and successive - items must have the same stride. The buffer must be uploaded to the GPU manually. Staging buffers - are appropriate for creating general constant or vertex buffer data. They can also write items in - reverse, which is how we render back-to-front when layers are visited front-to-back. They can be - uploaded to a `SharedBufferMLGPU` or an immutabler `MLGBuffer` very easily. Staging buffers are not - reference counted. - -Unsupported Features --------------------------------- - -Currently, these features of the old compositor are not yet implemented. - - - OpenGL and software support (currently AL only works on D3D11). - - APZ displayport overlay. - - Diagnostic/developer overlays other than the FPS/timing overlay. - - DEAA. It was never ported to the D3D11 compositor, but we would like it. - - Component alpha when used inside an opaque intermediate surface. - - Effects prefs. Possibly not needed post-B2G removal. - - Widget overlays and underlays used by macOS and Android. - - DefaultClearColor. This is Android specific, but is easy to added when needed. - - Frame uniformity info in the profiler. Possibly not needed post-B2G removal. - - LayerScope. There are no plans to make this work. - -Future Work --------------------------------- - - - Refactor for D3D12/Vulkan support (namely, split MLGDevice into something less stateful and something else more low-level). - - Remove "MLG" moniker and namespace everything. - - Other backends (D3D12/Vulkan, OpenGL, Software) - - Delete CompositorD3D11 - - Add DEAA support - - Re-enable the depth buffer by default for fast GPUs - - Re-enable right-sizing of inaccurately sized containers - - Drop constant buffers for ancillary vertex data - - Fast shader paths for simple video/painted layer cases - -History ----------- - -Advanced Layers has gone through four major design iterations. The initial version used tiling - -each render view divided the screen into 128x128 tiles, and layers were assigned to tiles based on -their screen-space draw area. This approach proved not to scale well to 3d transforms, and so -tiling was eliminated. - -We replaced it with a simple system of accumulating draw regions to each batch, thus ensuring that -items could be assigned to batches while maintaining correct z-ordering. This second iteration also -coincided with plane-splitting support. - -On large layer trees, accumulating the affected regions of batches proved to be quite expensive. -This led to a third iteration, using depth buffers and separate opaque and transparent batch lists -to achieve z-ordering and occlusion culling. - -Finally, depth buffers proved to be too expensive, and we introduced a simple CPU-based occlusion -culling pass. This iteration coincided with using more precise draw rects and splitting pipelines -into unit-quad, cpu-clipped and triangle-list, gpu-clipped variants. - diff --git a/gfx/layers/LayersHelpers.h b/gfx/layers/LayersHelpers.h index 99a3d24fa98e..dd88d8e5fcf7 100644 --- a/gfx/layers/LayersHelpers.h +++ b/gfx/layers/LayersHelpers.h @@ -10,7 +10,6 @@ #include "mozilla/gfx/Rect.h" #include "mozilla/gfx/Matrix.h" #include "mozilla/gfx/Polygon.h" -#include "nsRegion.h" #include "nsTArray.h" namespace mozilla { diff --git a/gfx/layers/apz/util/ContentProcessController.cpp b/gfx/layers/apz/util/ContentProcessController.cpp index ec0083a1f1b4..4e5f6108cb73 100644 --- a/gfx/layers/apz/util/ContentProcessController.cpp +++ b/gfx/layers/apz/util/ContentProcessController.cpp @@ -9,7 +9,6 @@ #include "mozilla/dom/TabChild.h" #include "mozilla/layers/APZCCallbackHelper.h" #include "mozilla/layers/APZChild.h" -#include "nsIContentInlines.h" #include "InputData.h" // for InputData diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 142d36a286af..97f1de5e5375 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -63,8 +63,6 @@ class TextRenderer; class CompositingRenderTarget; struct FPSState; class PaintCounter; -class LayerMLGPU; -class LayerManagerMLGPU; class UiCompositorControllerParent; static const int kVisualWarningDuration = 150; // ms @@ -125,9 +123,6 @@ public: virtual HostLayerManager* AsHostLayerManager() override { return this; } - virtual LayerManagerMLGPU* AsLayerManagerMLGPU() { - return nullptr; - } void ExtractImageCompositeNotifications(nsTArray* aNotifications) { @@ -555,8 +550,6 @@ public: virtual Layer* GetLayer() = 0; - virtual LayerMLGPU* AsLayerMLGPU() { return nullptr; } - virtual bool SetCompositableHost(CompositableHost*) { // We must handle this gracefully, see bug 967824 @@ -576,10 +569,6 @@ public: { mShadowVisibleRegion = aRegion; } - void SetShadowVisibleRegion(LayerIntRegion&& aRegion) - { - mShadowVisibleRegion = Move(aRegion); - } void SetShadowOpacity(float aOpacity) { @@ -607,12 +596,11 @@ public: // These getters can be used anytime. float GetShadowOpacity() { return mShadowOpacity; } const Maybe& GetShadowClipRect() { return mShadowClipRect; } - const LayerIntRegion& GetShadowVisibleRegion() const { return mShadowVisibleRegion; } + const LayerIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; } const gfx::Matrix4x4& GetShadowBaseTransform() { return mShadowTransform; } gfx::Matrix4x4 GetShadowTransform(); bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; } bool GetShadowOpacitySetByAnimation() { return mShadowOpacitySetByAnimation; } - LayerIntRegion&& GetShadowVisibleRegion() { return Move(mShadowVisibleRegion); } protected: HostLayerManager* mCompositorManager; diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 849343c0f3a1..882362ad6759 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -47,7 +47,7 @@ using namespace gfx; namespace layers { -bool CanUsePartialPresents(ID3D11Device* aDevice); +static bool CanUsePartialPresents(ID3D11Device* aDevice); const FLOAT sBlendFactor[] = { 0, 0, 0, 0 }; @@ -255,7 +255,7 @@ CompositorD3D11::Initialize(nsCString* const out_failureReason) return true; } -bool +static bool CanUsePartialPresents(ID3D11Device* aDevice) { if (gfxPrefs::PartialPresent() > 0) { diff --git a/gfx/layers/d3d11/MLGDeviceD3D11.cpp b/gfx/layers/d3d11/MLGDeviceD3D11.cpp deleted file mode 100644 index 98ceea54e754..000000000000 --- a/gfx/layers/d3d11/MLGDeviceD3D11.cpp +++ /dev/null @@ -1,1921 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "MLGDeviceD3D11.h" -#include "mozilla/ArrayUtils.h" -#include "mozilla/Telemetry.h" -#include "mozilla/WindowsVersion.h" -#include "mozilla/gfx/GPUParent.h" -#include "mozilla/gfx/StackArray.h" -#include "mozilla/layers/DiagnosticsD3D11.h" -#include "mozilla/layers/LayerMLGPU.h" -#include "mozilla/layers/ShaderDefinitionsMLGPU.h" -#include "mozilla/widget/CompositorWidget.h" -#include "mozilla/widget/WinCompositorWidget.h" -#include "MLGShaders.h" -#include "TextureD3D11.h" -#include "gfxPrefs.h" - -namespace mozilla { -namespace layers { - -using namespace mozilla::gfx; -using namespace mozilla::widget; -using namespace mozilla::layers::mlg; -using namespace std; - -// Defined in CompositorD3D11.cpp. -bool CanUsePartialPresents(ID3D11Device* aDevice); - -static D3D11_BOX RectToBox(const gfx::IntRect& aRect); - -MLGRenderTargetD3D11::MLGRenderTargetD3D11(const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags) - : MLGRenderTarget(aFlags), - mSize(aSize) -{ -} - -MLGRenderTargetD3D11::~MLGRenderTargetD3D11() -{ - ForgetTexture(); -} - -bool -MLGRenderTargetD3D11::Initialize(ID3D11Device* aDevice) -{ - D3D11_TEXTURE2D_DESC desc; - ::ZeroMemory(&desc, sizeof(desc)); - desc.Width = mSize.width; - desc.Height = mSize.height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.SampleDesc.Count = 1; - desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; - - RefPtr texture; - HRESULT hr = aDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture)); - if (FAILED(hr) || !texture) { - gfxCriticalNote << "Failed to create render target texture: " << hexa(hr); - return false; - } - - return Initialize(aDevice, texture); -} - -bool -MLGRenderTargetD3D11::Initialize(ID3D11Device* aDevice, ID3D11Texture2D* aTexture) -{ - if (!UpdateTexture(aTexture)) { - return false; - } - if ((mFlags & MLGRenderTargetFlags::ZBuffer) && !CreateDepthBuffer(aDevice)) { - return false; - } - return true; -} - -bool -MLGRenderTargetD3D11::UpdateTexture(ID3D11Texture2D* aTexture) -{ - // Save the view first, in case we can re-use it. - RefPtr view = mRTView.forget(); - - ForgetTexture(); - - if (!aTexture) { - return true; - } - -#ifdef DEBUG - D3D11_TEXTURE2D_DESC desc; - aTexture->GetDesc(&desc); - MOZ_ASSERT(desc.Width == mSize.width && desc.Height == mSize.height); -#endif - - RefPtr device; - aTexture->GetDevice(getter_AddRefs(device)); - - if (view) { - // Check that the view matches the backing texture. - RefPtr resource; - view->GetResource(getter_AddRefs(resource)); - if (resource != aTexture) { - view = nullptr; - } - } - - // If we couldn't re-use a view from before, make one now. - if (!view) { - HRESULT hr = device->CreateRenderTargetView(aTexture, nullptr, getter_AddRefs(view)); - if (FAILED(hr) || !view) { - gfxCriticalNote << "Failed to create render target view: " << hexa(hr); - return false; - } - } - - mTexture = aTexture; - mRTView = view.forget(); - return true; -} - -void -MLGRenderTargetD3D11::ForgetTexture() -{ - mTexture = nullptr; - mRTView = nullptr; - mTextureSource = nullptr; -} - -bool -MLGRenderTargetD3D11::CreateDepthBuffer(ID3D11Device* aDevice) -{ - D3D11_TEXTURE2D_DESC desc; - ::ZeroMemory(&desc, sizeof(desc)); - desc.Width = mSize.width; - desc.Height = mSize.height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_D32_FLOAT; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - - RefPtr buffer; - HRESULT hr = aDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(buffer)); - if (FAILED(hr) || !buffer) { - gfxCriticalNote << "Could not create depth-stencil buffer: " << hexa(hr); - return false; - } - - D3D11_DEPTH_STENCIL_VIEW_DESC viewDesc; - ::ZeroMemory(&viewDesc, sizeof(viewDesc)); - viewDesc.Format = DXGI_FORMAT_D32_FLOAT; - viewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - - RefPtr dsv; - hr = aDevice->CreateDepthStencilView(buffer, &viewDesc, getter_AddRefs(dsv)); - if (FAILED(hr) || !dsv) { - gfxCriticalNote << "Could not create depth-stencil view: " << hexa(hr); - return false; - } - - mDepthBuffer = buffer; - mDepthStencilView = dsv; - return true; -} - -ID3D11DepthStencilView* -MLGRenderTargetD3D11::GetDSV() -{ - return mDepthStencilView; -} - -ID3D11RenderTargetView* -MLGRenderTargetD3D11::GetRenderTargetView() -{ - return mRTView; -} - -IntSize -MLGRenderTargetD3D11::GetSize() const -{ - return mSize; -} - -MLGTexture* -MLGRenderTargetD3D11::GetTexture() -{ - if (!mTextureSource) { - mTextureSource = new MLGTextureD3D11(mTexture); - } - return mTextureSource; -} - -MLGSwapChainD3D11::MLGSwapChainD3D11(MLGDeviceD3D11* aParent, ID3D11Device* aDevice) - : mParent(aParent), - mDevice(aDevice), - mWidget(nullptr), - mCanUsePartialPresents(CanUsePartialPresents(aDevice)) -{ -} - -MLGSwapChainD3D11::~MLGSwapChainD3D11() -{ -} - -void -MLGSwapChainD3D11::Destroy() -{ - if (mRT == mParent->GetRenderTarget()) { - mParent->SetRenderTarget(nullptr); - } - mWidget = nullptr; - mRT = nullptr; - mSwapChain = nullptr; - mSwapChain1 = nullptr; -} - -RefPtr -MLGSwapChainD3D11::Create(MLGDeviceD3D11* aParent, ID3D11Device* aDevice, CompositorWidget* aWidget) -{ - RefPtr swapChain = new MLGSwapChainD3D11(aParent, aDevice); - if (!swapChain->Initialize(aWidget)) { - return nullptr; - } - return swapChain.forget(); -} - -bool -MLGSwapChainD3D11::Initialize(CompositorWidget* aWidget) -{ - HWND hwnd = aWidget->AsWindows()->GetHwnd(); - - RefPtr dxgiDevice; - mDevice->QueryInterface(dxgiDevice.StartAssignment()); - - RefPtr dxgiFactory; - { - RefPtr adapter; - dxgiDevice->GetAdapter(getter_AddRefs(adapter)); - - adapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment())); - } - - RefPtr dxgiFactory2; - if (gfxPrefs::Direct3D11UseDoubleBuffering() && - SUCCEEDED(dxgiFactory->QueryInterface(dxgiFactory2.StartAssignment())) && - dxgiFactory2 && - IsWin10OrLater()) - { - // DXGI_SCALING_NONE is not available on Windows 7 with the Platform Update: - // This looks awful for things like the awesome bar and browser window - // resizing, so we don't use a flip buffer chain here. (Note when using - // EFFECT_SEQUENTIAL Windows doesn't stretch the surface when resizing). - // - // We choose not to run this on platforms earlier than Windows 10 because - // it appears sometimes this breaks our ability to test ASAP compositing, - // which breaks Talos. - DXGI_SWAP_CHAIN_DESC1 desc; - ::ZeroMemory(&desc, sizeof(desc)); - desc.Width = 0; - desc.Height = 0; - desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.BufferCount = 2; - desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - desc.Scaling = DXGI_SCALING_NONE; - desc.Flags = 0; - - HRESULT hr = dxgiFactory2->CreateSwapChainForHwnd( - mDevice, - hwnd, - &desc, - nullptr, - nullptr, - getter_AddRefs(mSwapChain1)); - if (SUCCEEDED(hr) && mSwapChain1) { - DXGI_RGBA color = { 1.0f, 1.0f, 1.0f, 1.0f }; - mSwapChain1->SetBackgroundColor(&color); - mSwapChain = mSwapChain1; - mIsDoubleBuffered = true; - } - } - - if (!mSwapChain) { - DXGI_SWAP_CHAIN_DESC swapDesc; - ::ZeroMemory(&swapDesc, sizeof(swapDesc)); - swapDesc.BufferDesc.Width = 0; - swapDesc.BufferDesc.Height = 0; - swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - swapDesc.BufferDesc.RefreshRate.Numerator = 60; - swapDesc.BufferDesc.RefreshRate.Denominator = 1; - swapDesc.SampleDesc.Count = 1; - swapDesc.SampleDesc.Quality = 0; - swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapDesc.BufferCount = 1; - swapDesc.OutputWindow = hwnd; - swapDesc.Windowed = TRUE; - swapDesc.Flags = 0; - swapDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; - - HRESULT hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, getter_AddRefs(mSwapChain)); - if (FAILED(hr)) { - gfxCriticalNote << "Could not create swap chain: " << hexa(hr); - return false; - } - - // Try to get an IDXGISwapChain1 if we can, for partial presents. - mSwapChain->QueryInterface(mSwapChain1.StartAssignment()); - } - - // We need this because we don't want DXGI to respond to Alt+Enter. - dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_WINDOW_CHANGES); - mWidget = aWidget; - return true; -} - -RefPtr -MLGSwapChainD3D11::AcquireBackBuffer() -{ - RefPtr texture; - HRESULT hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), getter_AddRefs(texture)); - if (hr == DXGI_ERROR_INVALID_CALL && mDevice->GetDeviceRemovedReason() != S_OK) { - // This can happen on some drivers when there's a TDR. - mParent->HandleDeviceReset("SwapChain::GetBuffer"); - return nullptr; - } - if (FAILED(hr)) { - gfxCriticalNote << "Failed to acquire swap chain's backbuffer: " << hexa(hr); - return nullptr; - } - - if (!mRT) { - MLGRenderTargetFlags flags = MLGRenderTargetFlags::Default; - if (gfxPrefs::AdvancedLayersEnableDepthBuffer()) { - flags |= MLGRenderTargetFlags::ZBuffer; - } - - mRT = new MLGRenderTargetD3D11(mSize, flags); - if (!mRT->Initialize(mDevice, nullptr)) { - return nullptr; - } - } - - if (!mRT->UpdateTexture(texture)) { - return nullptr; - } - - if (mIsDoubleBuffered) { - UpdateBackBufferContents(texture); - } - return mRT; -} - -void -MLGSwapChainD3D11::UpdateBackBufferContents(ID3D11Texture2D* aBack) -{ - MOZ_ASSERT(mIsDoubleBuffered); - - // The front region contains the newly invalid region for this frame. The - // back region contains that, plus the region that was only drawn into the - // back buffer on the previous frame. Thus by subtracting the two, we can - // find the region that needs to be copied from the front buffer to the - // back. We do this so we don't have to re-render those pixels. - nsIntRegion frontValid; - frontValid.Sub(mBackBufferInvalid, mFrontBufferInvalid); - if (frontValid.IsEmpty()) { - return; - } - - RefPtr front; - HRESULT hr = mSwapChain->GetBuffer(1, __uuidof(ID3D11Texture2D), getter_AddRefs(front)); - if (FAILED(hr) || !front) { - return; - } - - RefPtr context; - mDevice->GetImmediateContext(getter_AddRefs(context)); - - for (auto iter = frontValid.RectIter(); !iter.Done(); iter.Next()) { - const IntRect& rect = iter.Get(); - D3D11_BOX box = RectToBox(rect); - context->CopySubresourceRegion(aBack, 0, rect.x, rect.y, 0, front, 0, &box); - } - - // The back and front buffers are now in sync. - mBackBufferInvalid = mFrontBufferInvalid; - MOZ_ASSERT(!mBackBufferInvalid.IsEmpty()); -} - -bool -MLGSwapChainD3D11::ResizeBuffers(const IntSize& aSize) -{ - // We have to clear all references to the old backbuffer before resizing. - mRT = nullptr; - - // Clear the size before re-allocating. If allocation fails we want to try - // again, because we had to sacrifice our original backbuffer to try - // resizing. - mSize = IntSize(0, 0); - - HRESULT hr = mSwapChain->ResizeBuffers(0, aSize.width, aSize.height, DXGI_FORMAT_B8G8R8A8_UNORM, 0); - if (hr == DXGI_ERROR_DEVICE_REMOVED) { - mParent->HandleDeviceReset("ResizeBuffers"); - return false; - } - if (FAILED(hr)) { - gfxCriticalNote << "Failed to resize swap chain buffers: " << hexa(hr); - return false; - } - - mSize = aSize; - mBackBufferInvalid = IntRect(IntPoint(0, 0), mSize); - mFrontBufferInvalid = IntRect(IntPoint(0, 0), mSize); - return true; -} - -IntSize -MLGSwapChainD3D11::GetSize() const -{ - return mSize; -} - -void -MLGSwapChainD3D11::Present() -{ - MOZ_ASSERT(!mBackBufferInvalid.IsEmpty()); - MOZ_ASSERT(mBackBufferInvalid.GetNumRects() > 0); - - // See bug 1260611 comment #28 for why we do this. - mParent->InsertPresentWaitQuery(); - - HRESULT hr; - if (mCanUsePartialPresents && mSwapChain1) { - StackArray rects(mBackBufferInvalid.GetNumRects()); - size_t i = 0; - for (auto iter = mBackBufferInvalid.RectIter(); !iter.Done(); iter.Next()) { - const IntRect& rect = iter.Get(); - rects[i].left = rect.x; - rects[i].top = rect.y; - rects[i].bottom = rect.YMost(); - rects[i].right = rect.XMost(); - i++; - } - - DXGI_PRESENT_PARAMETERS params; - PodZero(¶ms); - params.DirtyRectsCount = mBackBufferInvalid.GetNumRects(); - params.pDirtyRects = rects.data(); - hr = mSwapChain1->Present1(0, 0, ¶ms); - } else { - hr = mSwapChain->Present(0, 0); - } - - if (hr == DXGI_ERROR_DEVICE_REMOVED) { - mParent->HandleDeviceReset("Present"); - } - - if (FAILED(hr)) { - gfxCriticalNote << "D3D11 swap chain failed to present: " << hexa(hr); - } - - if (mIsDoubleBuffered) { - // Both the front and back buffer invalid regions are in sync, but now the - // presented buffer (the front buffer) is clean, so we clear its invalid - // region. The back buffer that will be used next frame however is now - // dirty. - MOZ_ASSERT(mFrontBufferInvalid.GetBounds() == mBackBufferInvalid.GetBounds()); - mFrontBufferInvalid.SetEmpty(); - } else { - mBackBufferInvalid.SetEmpty(); - } - mLastPresentSize = mSize; - - // Note: this waits on the query we inserted in the previous frame, - // not the one we just inserted now. Example: - // Insert query #1 - // Present #1 - // (first frame, no wait) - // Insert query #2 - // Present #2 - // Wait for query #1. - // Insert query #3 - // Present #3 - // Wait for query #2. - // - // This ensures we're done reading textures before swapping buffers. - mParent->WaitForPreviousPresentQuery(); -} - -void -MLGSwapChainD3D11::ForcePresent() -{ - DXGI_SWAP_CHAIN_DESC desc; - mSwapChain->GetDesc(&desc); - - LayoutDeviceIntSize size = mWidget->GetClientSize(); - - if (desc.BufferDesc.Width != size.width || desc.BufferDesc.Height != size.height) { - return; - } - - mSwapChain->Present(0, 0); - if (mIsDoubleBuffered) { - // Make sure we present the old front buffer since we know it is completely - // valid. This non-vsynced present should be pretty much 'free' for a flip - // chain. - mSwapChain->Present(0, 0); - } - - mLastPresentSize = mSize; -} - -void -MLGSwapChainD3D11::CopyBackbuffer(gfx::DrawTarget* aTarget, const gfx::IntRect& aBounds) -{ - RefPtr context; - mDevice->GetImmediateContext(getter_AddRefs(context)); - - RefPtr backbuffer; - HRESULT hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backbuffer.StartAssignment()); - if (FAILED(hr)) { - gfxWarning() << "Failed to acquire swapchain backbuffer: " << hexa(hr); - return; - } - - D3D11_TEXTURE2D_DESC bbDesc; - backbuffer->GetDesc(&bbDesc); - - CD3D11_TEXTURE2D_DESC tempDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height); - tempDesc.MipLevels = 1; - tempDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - tempDesc.Usage = D3D11_USAGE_STAGING; - tempDesc.BindFlags = 0; - - RefPtr temp; - hr = mDevice->CreateTexture2D(&tempDesc, nullptr, getter_AddRefs(temp)); - if (FAILED(hr)) { - gfxWarning() << "Failed to create a temporary texture for PresentAndCopy: " << hexa(hr); - return; - } - - context->CopyResource(temp, backbuffer); - - D3D11_MAPPED_SUBRESOURCE map; - hr = context->Map(temp, 0, D3D11_MAP_READ, 0, &map); - if (FAILED(hr)) { - gfxWarning() << "Failed to map temporary texture for PresentAndCopy: " << hexa(hr); - return; - } - - RefPtr source = Factory::CreateWrappingDataSourceSurface( - (uint8_t*)map.pData, - map.RowPitch, - IntSize(bbDesc.Width, bbDesc.Height), - SurfaceFormat::B8G8R8A8); - - aTarget->CopySurface( - source, - IntRect(0, 0, bbDesc.Width, bbDesc.Height), - IntPoint(-aBounds.x, -aBounds.y)); - aTarget->Flush(); - - context->Unmap(temp, 0); -} - -RefPtr -MLGBufferD3D11::Create(ID3D11Device* aDevice, - MLGBufferType aType, - uint32_t aSize, - MLGUsage aUsage, - const void* aInitialData) -{ - D3D11_BUFFER_DESC desc; - desc.ByteWidth = aSize; - desc.MiscFlags = 0; - desc.StructureByteStride = 0; - - switch (aUsage) { - case MLGUsage::Dynamic: - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - break; - case MLGUsage::Immutable: - desc.Usage = D3D11_USAGE_IMMUTABLE; - desc.CPUAccessFlags = 0; - break; - default: - MOZ_ASSERT_UNREACHABLE("Unknown buffer usage type"); - return nullptr; - } - - switch (aType) { - case MLGBufferType::Vertex: - desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - break; - case MLGBufferType::Constant: - desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - break; - default: - MOZ_ASSERT_UNREACHABLE("Unknown buffer type"); - return nullptr; - } - - D3D11_SUBRESOURCE_DATA data; - data.pSysMem = aInitialData; - data.SysMemPitch = aSize; - data.SysMemSlicePitch = 0; - - RefPtr buffer; - aDevice->CreateBuffer(&desc, aInitialData ? &data : nullptr, getter_AddRefs(buffer)); - - return new MLGBufferD3D11(buffer, aType, aSize); -} - -MLGBufferD3D11::MLGBufferD3D11(ID3D11Buffer* aBuffer, MLGBufferType aType, size_t aSize) - : mBuffer(aBuffer), - mType(aType), - mSize(aSize) -{ -} - -MLGBufferD3D11::~MLGBufferD3D11() -{ -} - -MLGTextureD3D11::MLGTextureD3D11(ID3D11Texture2D* aTexture) - : mTexture(aTexture) -{ - D3D11_TEXTURE2D_DESC desc; - aTexture->GetDesc(&desc); - - mSize.width = desc.Width; - mSize.height = desc.Height; -} - -/* static */ RefPtr -MLGTextureD3D11::Create(ID3D11Device* aDevice, - const gfx::IntSize& aSize, - gfx::SurfaceFormat aFormat, - MLGUsage aUsage, - MLGTextureFlags aFlags) -{ - D3D11_TEXTURE2D_DESC desc; - ::ZeroMemory(&desc, sizeof(desc)); - desc.Width = aSize.width; - desc.Height = aSize.height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.SampleDesc.Count = 1; - - switch (aFormat) { - case SurfaceFormat::B8G8R8A8: - desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - break; - default: - MOZ_ASSERT_UNREACHABLE("Unsupported surface format"); - return nullptr; - } - - switch (aUsage) { - case MLGUsage::Immutable: - desc.Usage = D3D11_USAGE_IMMUTABLE; - break; - case MLGUsage::Default: - desc.Usage = D3D11_USAGE_DEFAULT; - break; - case MLGUsage::Dynamic: - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - break; - case MLGUsage::Staging: - desc.Usage = D3D11_USAGE_STAGING; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - break; - default: - MOZ_ASSERT_UNREACHABLE("Unsupported usage type"); - break; - } - - if (aFlags & MLGTextureFlags::ShaderResource) { - desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; - } - if (aFlags & MLGTextureFlags::RenderTarget) { - desc.BindFlags |= D3D11_BIND_RENDER_TARGET; - } - - RefPtr texture; - HRESULT hr = aDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture)); - if (FAILED(hr) || !texture) { - gfxCriticalNote << "Failed to create 2D texture: " << hexa(hr); - return nullptr; - } - - ReportTextureMemoryUsage(texture, aSize.width * aSize.height * 4); - - return new MLGTextureD3D11(texture); -} - -ID3D11ShaderResourceView* -MLGTextureD3D11::GetShaderResourceView() -{ - if (!mView) { - RefPtr device; - mTexture->GetDevice(getter_AddRefs(device)); - - HRESULT hr = device->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mView)); - if (FAILED(hr) || !mView) { - gfxWarning() << "Could not create shader resource view: " << hexa(hr); - return nullptr; - } - } - return mView; -} - -MLGDeviceD3D11::MLGDeviceD3D11(ID3D11Device* aDevice) - : mDevice(aDevice) - , mScissored(false) -{ -} - -MLGDeviceD3D11::~MLGDeviceD3D11() -{ - // Caller should have unlocked all textures after presenting. - MOZ_ASSERT(mLockedTextures.IsEmpty()); - MOZ_ASSERT(mLockAttemptedTextures.IsEmpty()); -} - -bool -MLGDeviceD3D11::Initialize() -{ - if (!mDevice) { - return Fail("FEATURE_FAILURE_NO_DEVICE"); - } - - if (mDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) { - return Fail("FEATURE_FAILURE_NEED_LEVEL_10_0"); - } - - mDevice->GetImmediateContext(getter_AddRefs(mCtx)); - if (!mCtx) { - return Fail("FEATURE_FAILURE_NO_CONTEXT"); - } - - mCtx->QueryInterface((ID3D11DeviceContext1**)getter_AddRefs(mCtx1)); - - if (mCtx1) { - // Windows 7 can have Direct3D 11.1 if the platform update is installed, - // but according to some NVIDIA presentations it is known to be buggy. - // It's not clear whether that only refers to command list emulation, - // or whether it just has performance penalties. To be safe we only use - // it on Windows 8 or higher. - // - // https://docs.microsoft.com/en-us/windows-hardware/drivers/display/directx-feature-improvements-in-windows-8#buffers - D3D11_FEATURE_DATA_D3D11_OPTIONS options; - HRESULT hr = mDevice->CheckFeatureSupport( - D3D11_FEATURE_D3D11_OPTIONS, - &options, - sizeof(options)); - if (SUCCEEDED(hr)) { - if (IsWin8OrLater()) { - mCanUseConstantBufferOffsetBinding = (options.ConstantBufferOffsetting != FALSE); - } - mCanUseClearView = (options.ClearView != FALSE); - } - } - - // Get capabilities. - switch (mDevice->GetFeatureLevel()) { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - mMaxConstantBufferBindSize = D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16; - break; - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - mMaxConstantBufferBindSize = D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16; - break; - default: - MOZ_ASSERT_UNREACHABLE("Unknown feature level"); - } - - mDiagnostics = MakeUnique(mDevice, mCtx); - - { - struct Vertex2D { float x; float y; }; - Vertex2D vertices[] = { { 0, 0 }, { 1.0f, 0 }, { 0, 1.0f }, { 1.0f, 1.0f } }; - mUnitQuadVB = CreateBuffer( - MLGBufferType::Vertex, - sizeof(Vertex2D) * 4, - MLGUsage::Immutable, - &vertices); - if (!mUnitQuadVB) { - return Fail("FEATURE_FAILURE_UNIT_QUAD_BUFFER"); - } - } - - // Define pixel shaders. -#define LAZY_PS(cxxName, enumName) mLazyPixelShaders[PixelShaderID::enumName] = &s##cxxName; - LAZY_PS(TexturedVertexRGB, TexturedVertexRGB); - LAZY_PS(TexturedVertexRGBA, TexturedVertexRGBA); - LAZY_PS(TexturedQuadRGB, TexturedQuadRGB); - LAZY_PS(TexturedQuadRGBA, TexturedQuadRGBA); - LAZY_PS(ColoredQuadPS, ColoredQuad); - LAZY_PS(ColoredVertexPS, ColoredVertex); - LAZY_PS(ComponentAlphaQuadPS, ComponentAlphaQuad); - LAZY_PS(ComponentAlphaVertexPS, ComponentAlphaVertex); - LAZY_PS(TexturedVertexIMC4, TexturedVertexIMC4); - LAZY_PS(TexturedVertexNV12, TexturedVertexNV12); - LAZY_PS(TexturedQuadIMC4, TexturedQuadIMC4); - LAZY_PS(TexturedQuadNV12, TexturedQuadNV12); - LAZY_PS(BlendMultiplyPS, BlendMultiply); - LAZY_PS(BlendScreenPS, BlendScreen); - LAZY_PS(BlendOverlayPS, BlendOverlay); - LAZY_PS(BlendDarkenPS, BlendDarken); - LAZY_PS(BlendLightenPS, BlendLighten); - LAZY_PS(BlendColorDodgePS, BlendColorDodge); - LAZY_PS(BlendColorBurnPS, BlendColorBurn); - LAZY_PS(BlendHardLightPS, BlendHardLight); - LAZY_PS(BlendSoftLightPS, BlendSoftLight); - LAZY_PS(BlendDifferencePS, BlendDifference); - LAZY_PS(BlendExclusionPS, BlendExclusion); - LAZY_PS(BlendHuePS, BlendHue); - LAZY_PS(BlendSaturationPS, BlendSaturation); - LAZY_PS(BlendColorPS, BlendColor); - LAZY_PS(BlendLuminosityPS, BlendLuminosity); - LAZY_PS(ClearPS, Clear); - LAZY_PS(MaskCombinerPS, MaskCombiner); - LAZY_PS(DiagnosticTextPS, DiagnosticText); -#undef LAZY_PS - - // Define vertex shaders. -#define LAZY_VS(cxxName, enumName) mLazyVertexShaders[VertexShaderID::enumName] = &s##cxxName; - LAZY_VS(TexturedQuadVS, TexturedQuad); - LAZY_VS(TexturedVertexVS, TexturedVertex); - LAZY_VS(BlendVertexVS, BlendVertex); - LAZY_VS(ColoredQuadVS, ColoredQuad); - LAZY_VS(ColoredVertexVS, ColoredVertex); - LAZY_VS(ClearVS, Clear); - LAZY_VS(MaskCombinerVS, MaskCombiner); - LAZY_VS(DiagnosticTextVS, DiagnosticText); -#undef LAZY_VS - - // Force critical shaders to initialize early. - if (!InitPixelShader(PixelShaderID::TexturedQuadRGB) || - !InitPixelShader(PixelShaderID::TexturedQuadRGBA) || - !InitPixelShader(PixelShaderID::ColoredQuad) || - !InitPixelShader(PixelShaderID::ComponentAlphaQuad) || - !InitPixelShader(PixelShaderID::Clear) || - !InitVertexShader(VertexShaderID::TexturedQuad) || - !InitVertexShader(VertexShaderID::ColoredQuad) || - !InitVertexShader(VertexShaderID::Clear)) - { - return Fail("FEATURE_FAILURE_CRITICAL_SHADER_FAILURE"); - } - - // Initialize input layouts. - { - D3D11_INPUT_ELEMENT_DESC inputDesc[] = { - // vPos - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vRect - { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, - // vLayerOffset - { "TEXCOORD", 1, DXGI_FORMAT_R32_UINT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, - // vDepth - { "TEXCOORD", 2, DXGI_FORMAT_R32_SINT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, - }; - if (!InitInputLayout(inputDesc, MOZ_ARRAY_LENGTH(inputDesc), sTexturedQuadVS, VertexShaderID::TexturedQuad)) { - return Fail("FEATURE_FAILURE_UNIT_QUAD_INPUT_LAYOUT"); - } - // Propagate the input layout to other vertex shaders that use the same. - // All quad-based layer shaders use the same layout. - mInputLayouts[VertexShaderID::ColoredQuad] = mInputLayouts[VertexShaderID::TexturedQuad]; - } - { - D3D11_INPUT_ELEMENT_DESC inputDesc[] = { - // vLayerPos - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vTexCoord - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vLayerOffset - { "TEXCOORD", 1, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vDepth - { "TEXCOORD", 2, DXGI_FORMAT_R32_SINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - if (!InitInputLayout(inputDesc, MOZ_ARRAY_LENGTH(inputDesc), sTexturedVertexVS, VertexShaderID::TexturedVertex)) { - return Fail("FEATURE_FAILURE_TEXTURED_INPUT_LAYOUT"); - } - // Propagate the input layout to other vertex shaders that use the same. - mInputLayouts[VertexShaderID::BlendVertex] = mInputLayouts[VertexShaderID::TexturedVertex]; - } - { - D3D11_INPUT_ELEMENT_DESC inputDesc[] = { - // vPos - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vLayerOffset - { "TEXCOORD", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vDepth - { "TEXCOORD", 1, DXGI_FORMAT_R32_SINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vIndex - { "TEXCOORD", 2, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - if (!InitInputLayout(inputDesc, MOZ_ARRAY_LENGTH(inputDesc), sColoredVertexVS, VertexShaderID::ColoredVertex)) { - return Fail("FEATURE_FAILURE_COLORED_INPUT_LAYOUT"); - } - } - { - D3D11_INPUT_ELEMENT_DESC inputDesc[] = { - // vPos - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vRect - { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_SINT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, - // vDepth - { "TEXCOORD", 1, DXGI_FORMAT_R32_SINT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, - }; - if (!InitInputLayout(inputDesc, MOZ_ARRAY_LENGTH(inputDesc), sClearVS, VertexShaderID::Clear)) { - return Fail("FEATURE_FAILURE_CLEAR_INPUT_LAYOUT"); - } - } - { - D3D11_INPUT_ELEMENT_DESC inputDesc[] = { - // vPos - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vTexCoords - { "POSITION", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1 } - }; - if (!InitInputLayout(inputDesc, MOZ_ARRAY_LENGTH(inputDesc), sMaskCombinerVS, VertexShaderID::MaskCombiner)) { - return Fail("FEATURE_FAILURE_MASK_COMBINER_INPUT_LAYOUT"); - } - } - { - D3D11_INPUT_ELEMENT_DESC inputDesc[] = { - // vPos - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - // vRect - { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, - // vTexCoords - { "TEXCOORD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, - }; - if (!InitInputLayout(inputDesc, MOZ_ARRAY_LENGTH(inputDesc), sDiagnosticTextVS, VertexShaderID::DiagnosticText)) { - return Fail("FEATURE_FAILURE_DIAGNOSTIC_INPUT_LAYOUT"); - } - } - - if (!InitRasterizerStates() || - !InitDepthStencilState() || - !InitBlendStates() || - !InitSamplerStates() || - !InitSyncObject()) - { - return false; - } - - mCtx->RSSetState(mRasterizerStateNoScissor); - return MLGDevice::Initialize(); -} - -bool -MLGDeviceD3D11::InitPixelShader(PixelShaderID aShaderID) -{ - const ShaderBytes* code = mLazyPixelShaders[aShaderID]; - HRESULT hr = mDevice->CreatePixelShader( - code->mData, - code->mLength, - nullptr, - getter_AddRefs(mPixelShaders[aShaderID])); - if (FAILED(hr)) { - gfxCriticalNote << "Could not create pixel shader " << hexa(unsigned(aShaderID)) << ": " << hexa(hr); - return false; - } - return true; -} - -bool -MLGDeviceD3D11::InitRasterizerStates() -{ - { - CD3D11_RASTERIZER_DESC desc = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT()); - desc.CullMode = D3D11_CULL_NONE; - desc.FillMode = D3D11_FILL_SOLID; - desc.ScissorEnable = TRUE; - HRESULT hr = mDevice->CreateRasterizerState(&desc, getter_AddRefs(mRasterizerStateScissor)); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_SCISSOR_RASTERIZER", - "Could not create scissor rasterizer (%x)", hr); - } - } - { - CD3D11_RASTERIZER_DESC desc = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT()); - desc.CullMode = D3D11_CULL_NONE; - desc.FillMode = D3D11_FILL_SOLID; - HRESULT hr = mDevice->CreateRasterizerState(&desc, getter_AddRefs(mRasterizerStateNoScissor)); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_DEFAULT_RASTERIZER", - "Could not create default rasterizer (%x)", hr); - } - } - return true; -} - -bool -MLGDeviceD3D11::InitSamplerStates() -{ - { - CD3D11_SAMPLER_DESC desc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); - HRESULT hr = mDevice->CreateSamplerState(&desc, getter_AddRefs(mSamplerStates[SamplerMode::LinearClamp])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_LINEAR_CLAMP_SAMPLER", - "Could not create linear clamp sampler (%x)", hr); - } - } - { - CD3D11_SAMPLER_DESC desc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); - desc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER; - desc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER; - desc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER; - memset(desc.BorderColor, 0, sizeof(desc.BorderColor)); - HRESULT hr = mDevice->CreateSamplerState(&desc, getter_AddRefs(mSamplerStates[SamplerMode::LinearClampToZero])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_LINEAR_CLAMP_ZERO_SAMPLER", - "Could not create linear clamp to zero sampler (%x)", hr); - } - } - - { - CD3D11_SAMPLER_DESC desc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); - desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - HRESULT hr = mDevice->CreateSamplerState(&desc, getter_AddRefs(mSamplerStates[SamplerMode::Point])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_POINT_SAMPLER", - "Could not create point sampler (%x)", hr); - } - } - return true; -} - -bool -MLGDeviceD3D11::InitBlendStates() -{ - { - CD3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); - HRESULT hr = mDevice->CreateBlendState(&desc, getter_AddRefs(mBlendStates[MLGBlendState::Copy])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_COPY_BLEND_STATE", - "Could not create copy blend state (%x)", hr); - } - } - - { - CD3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); - desc.RenderTarget[0].BlendEnable = TRUE; - desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - HRESULT hr = mDevice->CreateBlendState(&desc, getter_AddRefs(mBlendStates[MLGBlendState::Over])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_OVER_BLEND_STATE", - "Could not create over blend state (%x)", hr); - } - } - - { - CD3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); - desc.RenderTarget[0].BlendEnable = TRUE; - desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - HRESULT hr = mDevice->CreateBlendState(&desc, getter_AddRefs(mBlendStates[MLGBlendState::OverAndPremultiply])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_OVER_BLEND_STATE", - "Could not create over blend state (%x)", hr); - } - } - - { - CD3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); - desc.RenderTarget[0].BlendEnable = TRUE; - desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; - desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_MIN; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; - desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_MIN; - HRESULT hr = mDevice->CreateBlendState(&desc, getter_AddRefs(mBlendStates[MLGBlendState::Min])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_MIN_BLEND_STATE", - "Could not create min blend state (%x)", hr); - } - } - - { - CD3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); - desc.RenderTarget[0].BlendEnable = TRUE; - desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC1_COLOR; - desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - HRESULT hr = mDevice->CreateBlendState(&desc, getter_AddRefs(mBlendStates[MLGBlendState::ComponentAlpha])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_COMPONENT_ALPHA_BLEND_STATE", - "Could not create component alpha blend state (%x)", hr); - } - } - return true; -} - -bool -MLGDeviceD3D11::InitDepthStencilState() -{ - D3D11_DEPTH_STENCIL_DESC desc = CD3D11_DEPTH_STENCIL_DESC(D3D11_DEFAULT); - - HRESULT hr = mDevice->CreateDepthStencilState( - &desc, getter_AddRefs(mDepthStencilStates[MLGDepthTestMode::Write])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_WRITE_DEPTH_STATE", - "Could not create write depth stencil state (%x)", hr); - } - - desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - hr = mDevice->CreateDepthStencilState( - &desc, getter_AddRefs(mDepthStencilStates[MLGDepthTestMode::ReadOnly])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_READ_DEPTH_STATE", - "Could not create read depth stencil state (%x)", hr); - } - - desc.DepthEnable = FALSE; - hr = mDevice->CreateDepthStencilState( - &desc, getter_AddRefs(mDepthStencilStates[MLGDepthTestMode::Disabled])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_DISABLED_DEPTH_STATE", - "Could not create disabled depth stencil state (%x)", hr); - } - - desc = CD3D11_DEPTH_STENCIL_DESC(D3D11_DEFAULT); - desc.DepthFunc = D3D11_COMPARISON_ALWAYS; - hr = mDevice->CreateDepthStencilState( - &desc, getter_AddRefs(mDepthStencilStates[MLGDepthTestMode::AlwaysWrite])); - if (FAILED(hr)) { - return Fail("FEATURE_FAILURE_WRITE_DEPTH_STATE", - "Could not create always-write depth stencil state (%x)", hr); - } - - return true; -} - -bool -MLGDeviceD3D11::InitVertexShader(VertexShaderID aShaderID) -{ - const ShaderBytes* code = mLazyVertexShaders[aShaderID]; - HRESULT hr = mDevice->CreateVertexShader( - code->mData, - code->mLength, - nullptr, - getter_AddRefs(mVertexShaders[aShaderID])); - if (FAILED(hr)) { - gfxCriticalNote << "Could not create vertex shader " << hexa(unsigned(aShaderID)) << ": " << hexa(hr); - return false; - } - return true; -} - -bool -MLGDeviceD3D11::InitInputLayout(D3D11_INPUT_ELEMENT_DESC* aDesc, - size_t aNumElements, - const ShaderBytes& aCode, - VertexShaderID aShaderID) -{ - HRESULT hr = mDevice->CreateInputLayout( - aDesc, - aNumElements, - aCode.mData, - aCode.mLength, - getter_AddRefs(mInputLayouts[aShaderID])); - if (FAILED(hr)) { - gfxCriticalNote << "Could not create input layout for shader " - << hexa(unsigned(aShaderID)) - << ": " << hexa(hr); - return false; - } - return true; -} - -TextureFactoryIdentifier -MLGDeviceD3D11::GetTextureFactoryIdentifier() const -{ - TextureFactoryIdentifier ident( - GetLayersBackend(), - XRE_GetProcessType(), - GetMaxTextureSize()); - ident.mSyncHandle = mSyncHandle; - return ident; -} - -inline uint32_t GetMaxTextureSizeForFeatureLevel1(D3D_FEATURE_LEVEL aFeatureLevel) -{ - int32_t maxTextureSize; - switch (aFeatureLevel) { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; - break; - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - maxTextureSize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; - break; - case D3D_FEATURE_LEVEL_9_3: - maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; - break; - default: - maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; - } - return maxTextureSize; -} - -LayersBackend -MLGDeviceD3D11::GetLayersBackend() const -{ - return LayersBackend::LAYERS_D3D11; -} - -int32_t -MLGDeviceD3D11::GetMaxTextureSize() const -{ - return GetMaxTextureSizeForFeatureLevel1(mDevice->GetFeatureLevel()); -} - -RefPtr -MLGDeviceD3D11::CreateSwapChainForWidget(widget::CompositorWidget* aWidget) -{ - return MLGSwapChainD3D11::Create(this, mDevice, aWidget); -} - -RefPtr -MLGDeviceD3D11::CreateDataTextureSource(TextureFlags aFlags) -{ - return new DataTextureSourceD3D11(mDevice, gfx::SurfaceFormat::UNKNOWN, aFlags); -} - -static inline D3D11_MAP -ToD3D11Map(MLGMapType aType) -{ - switch (aType) { - case MLGMapType::READ: - return D3D11_MAP_READ; - case MLGMapType::READ_WRITE: - return D3D11_MAP_READ_WRITE; - case MLGMapType::WRITE: - return D3D11_MAP_WRITE; - case MLGMapType::WRITE_DISCARD: - return D3D11_MAP_WRITE_DISCARD; - } - return D3D11_MAP_WRITE; -} - -bool -MLGDeviceD3D11::Map(MLGResource* aResource, MLGMapType aType, MLGMappedResource* aMap) -{ - ID3D11Resource* resource = aResource->AsResourceD3D11()->GetResource(); - - D3D11_MAPPED_SUBRESOURCE map; - HRESULT hr = mCtx->Map(resource, 0, ToD3D11Map(aType), 0, &map); - - if (FAILED(hr)) { - gfxWarning() << "Could not map MLG resource: " << hexa(hr); - return false; - } - - aMap->mData = reinterpret_cast(map.pData); - aMap->mStride = map.RowPitch; - return true; -} - -void -MLGDeviceD3D11::Unmap(MLGResource* aResource) -{ - ID3D11Resource* resource = aResource->AsResourceD3D11()->GetResource(); - mCtx->Unmap(resource, 0); -} - -void -MLGDeviceD3D11::UpdatePartialResource(MLGResource* aResource, - const gfx::IntRect* aRect, - void* aData, uint32_t aStride) -{ - D3D11_BOX box; - if (aRect) { - box = RectToBox(*aRect); - } - - ID3D11Resource* resource = aResource->AsResourceD3D11()->GetResource(); - mCtx->UpdateSubresource(resource, 0, aRect ? &box : nullptr, aData, aStride, 0); -} - -void -MLGDeviceD3D11::SetRenderTarget(MLGRenderTarget* aRT) -{ - ID3D11RenderTargetView* rtv = nullptr; - ID3D11DepthStencilView* dsv = nullptr; - - if (aRT) { - MLGRenderTargetD3D11* rt = aRT->AsD3D11(); - rtv = rt->GetRenderTargetView(); - dsv = rt->GetDSV(); - } - - mCtx->OMSetRenderTargets(1, &rtv, dsv); - mCurrentRT = aRT; -} - -MLGRenderTarget* -MLGDeviceD3D11::GetRenderTarget() -{ - return mCurrentRT; -} - -void -MLGDeviceD3D11::SetViewport(const gfx::IntRect& aViewport) -{ - D3D11_VIEWPORT vp; - vp.MaxDepth = 1.0f; - vp.MinDepth = 0.0f; - vp.TopLeftX = aViewport.x; - vp.TopLeftY = aViewport.y; - vp.Width = aViewport.width; - vp.Height = aViewport.height; - mCtx->RSSetViewports(1, &vp); -} - -static inline D3D11_RECT -ToD3D11Rect(const gfx::IntRect& aRect) -{ - D3D11_RECT rect; - rect.left = aRect.x; - rect.top = aRect.y; - rect.right = aRect.XMost(); - rect.bottom = aRect.YMost(); - return rect; -} - -void -MLGDeviceD3D11::SetScissorRect(const Maybe& aScissorRect) -{ - if (!aScissorRect) { - if (mScissored) { - mCtx->RSSetState(mRasterizerStateNoScissor); - mScissored = false; - } - return; - } - D3D11_RECT rect = ToD3D11Rect(aScissorRect.value()); - mCtx->RSSetScissorRects(1, &rect); - if (!mScissored) { - mScissored = true; - mCtx->RSSetState(mRasterizerStateScissor); - } -} - -void -MLGDeviceD3D11::SetVertexShader(VertexShaderID aShader) -{ - if (!mVertexShaders[aShader]) { - InitVertexShader(aShader); - MOZ_ASSERT(mInputLayouts[aShader]); - } - if (mCurrentVertexShader != mVertexShaders[aShader]) { - mCtx->VSSetShader(mVertexShaders[aShader], nullptr, 0); - mCurrentVertexShader = mVertexShaders[aShader]; - } - if (mCurrentInputLayout != mInputLayouts[aShader]) { - mCtx->IASetInputLayout(mInputLayouts[aShader]); - mCurrentInputLayout = mInputLayouts[aShader]; - } -} - -void -MLGDeviceD3D11::SetPixelShader(PixelShaderID aShader) -{ - if (!mPixelShaders[aShader]) { - InitPixelShader(aShader); - } - if (mCurrentPixelShader != mPixelShaders[aShader]) { - mCtx->PSSetShader(mPixelShaders[aShader], nullptr, 0); - mCurrentPixelShader = mPixelShaders[aShader]; - } -} - -void -MLGDeviceD3D11::SetSamplerMode(uint32_t aIndex, SamplerMode aMode) -{ - ID3D11SamplerState* sampler = mSamplerStates[aMode]; - mCtx->PSSetSamplers(aIndex, 1, &sampler); -} - -void -MLGDeviceD3D11::SetBlendState(MLGBlendState aState) -{ - if (mCurrentBlendState != mBlendStates[aState]) { - FLOAT blendFactor[4] = { 0, 0, 0, 0 }; - mCtx->OMSetBlendState(mBlendStates[aState], blendFactor, 0xFFFFFFFF); - mCurrentBlendState = mBlendStates[aState]; - } -} - -void -MLGDeviceD3D11::SetVertexBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aStride, uint32_t aOffset) -{ - ID3D11Buffer* buffer = aBuffer ? aBuffer->AsD3D11()->GetBuffer() : nullptr; - mCtx->IASetVertexBuffers(aSlot, 1, &buffer, &aStride, &aOffset); -} - -void -MLGDeviceD3D11::SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) -{ - MOZ_ASSERT(aSlot < kMaxVertexShaderConstantBuffers); - - ID3D11Buffer* buffer = aBuffer ? aBuffer->AsD3D11()->GetBuffer() : nullptr; - mCtx->VSSetConstantBuffers(aSlot, 1, &buffer); -} - -void -MLGDeviceD3D11::SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) -{ - MOZ_ASSERT(aSlot < kMaxPixelShaderConstantBuffers); - - ID3D11Buffer* buffer = aBuffer ? aBuffer->AsD3D11()->GetBuffer() : nullptr; - mCtx->PSSetConstantBuffers(aSlot, 1, &buffer); -} - -void -MLGDeviceD3D11::SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aFirstConstant, uint32_t aNumConstants) -{ - MOZ_ASSERT(aSlot < kMaxVertexShaderConstantBuffers); - MOZ_ASSERT(mCanUseConstantBufferOffsetBinding); - MOZ_ASSERT(mCtx1); - MOZ_ASSERT(aFirstConstant % 16 == 0); - - ID3D11Buffer* buffer = aBuffer ? aBuffer->AsD3D11()->GetBuffer() : nullptr; - mCtx1->VSSetConstantBuffers1(aSlot, 1, &buffer, &aFirstConstant, &aNumConstants); -} - -void -MLGDeviceD3D11::SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aFirstConstant, uint32_t aNumConstants) -{ - MOZ_ASSERT(aSlot < kMaxPixelShaderConstantBuffers); - MOZ_ASSERT(mCanUseConstantBufferOffsetBinding); - MOZ_ASSERT(mCtx1); - MOZ_ASSERT(aFirstConstant % 16 == 0); - - ID3D11Buffer* buffer = aBuffer ? aBuffer->AsD3D11()->GetBuffer() : nullptr; - mCtx1->PSSetConstantBuffers1(aSlot, 1, &buffer, &aFirstConstant, &aNumConstants); -} - -void -MLGDeviceD3D11::SetPrimitiveTopology(MLGPrimitiveTopology aTopology) -{ - D3D11_PRIMITIVE_TOPOLOGY topology; - switch (aTopology) { - case MLGPrimitiveTopology::TriangleStrip: - topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - break; - case MLGPrimitiveTopology::TriangleList: - topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - break; - case MLGPrimitiveTopology::UnitQuad: { - SetVertexBuffer(0, mUnitQuadVB, sizeof(float) * 2, 0); - topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - break; - } - default: - MOZ_ASSERT_UNREACHABLE("Unknown topology"); - break; - } - - mCtx->IASetPrimitiveTopology(topology); -} - -RefPtr -MLGDeviceD3D11::CreateBuffer(MLGBufferType aType, - uint32_t aSize, - MLGUsage aUsage, - const void* aInitialData) -{ - return MLGBufferD3D11::Create(mDevice, aType, aSize, aUsage, aInitialData); -} - -RefPtr -MLGDeviceD3D11::CreateRenderTarget(const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags) -{ - RefPtr rt = new MLGRenderTargetD3D11(aSize, aFlags); - if (!rt->Initialize(mDevice)) { - return nullptr; - } - return rt; -} - -void -MLGDeviceD3D11::Clear(MLGRenderTarget* aRT, const gfx::Color& aColor) -{ - MLGRenderTargetD3D11* rt = aRT->AsD3D11(); - FLOAT rgba[4] = { aColor.r, aColor.g, aColor.b, aColor.a }; - mCtx->ClearRenderTargetView(rt->GetRenderTargetView(), rgba); - if (ID3D11DepthStencilView* dsv = rt->GetDSV()) { - mCtx->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH, 1.0, 0); - } -} - -void -MLGDeviceD3D11::ClearDepthBuffer(MLGRenderTarget* aRT) -{ - MLGRenderTargetD3D11* rt = aRT->AsD3D11(); - if (ID3D11DepthStencilView* dsv = rt->GetDSV()) { - mCtx->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH, 1.0, 0); - } -} - -void -MLGDeviceD3D11::ClearView(MLGRenderTarget* aRT, - const Color& aColor, - const IntRect* aRects, - size_t aNumRects) -{ - MOZ_ASSERT(mCanUseClearView); - MOZ_ASSERT(mCtx1); - - MLGRenderTargetD3D11* rt = aRT->AsD3D11(); - FLOAT rgba[4] = { aColor.r, aColor.g, aColor.b, aColor.a }; - - StackArray rects(aNumRects); - for (size_t i = 0; i < aNumRects; i++) { - rects[i] = ToD3D11Rect(aRects[i]); - } - - // Batch ClearView calls since too many will crash NVIDIA drivers. - size_t remaining = aNumRects; - size_t cursor = 0; - while (remaining > 0) { - size_t amount = std::min(remaining, kMaxClearViewRects); - mCtx1->ClearView(rt->GetRenderTargetView(), rgba, rects.data() + cursor, amount); - - remaining -= amount; - cursor += amount; - } -} - -void -MLGDeviceD3D11::Draw(uint32_t aVertexCount, uint32_t aOffset) -{ - mCtx->Draw(aVertexCount, aOffset); -} - -void -MLGDeviceD3D11::DrawInstanced(uint32_t aVertexCountPerInstance, uint32_t aInstanceCount, - uint32_t aVertexOffset, uint32_t aInstanceOffset) -{ - mCtx->DrawInstanced(aVertexCountPerInstance, aInstanceCount, aVertexOffset, aInstanceOffset); -} - -void -MLGDeviceD3D11::SetPSTextures(uint32_t aSlot, uint32_t aNumTextures, TextureSource* const* aTextures) -{ - StackArray textures(aNumTextures); - - for (size_t i = 0; i < aNumTextures; i++) { - if (!aTextures[i]) { - gfxWarning() << "Null TextureRef in SetPSTextures"; - continue; - } - - ID3D11ShaderResourceView* view = nullptr; - if (TextureSourceD3D11* source = aTextures[i]->AsSourceD3D11()) { - ID3D11Texture2D* texture = source->GetD3D11Texture(); - if (!texture) { - gfxWarning() << "No D3D11 texture present in SetPSTextures"; - continue; - } - MaybeLockTexture(texture); - - view = source->GetShaderResourceView(); - } else { - gfxWarning() << "Unknown texture type in SetPSTextures"; - continue; - } - - if (!view) { - gfxWarning() << "Failed to get shader resource view for texture"; - continue; - } - textures[i] = view; - } - - mCtx->PSSetShaderResources(aSlot, aNumTextures, textures.data()); -} - -void -MLGDeviceD3D11::SetPSTexture(uint32_t aSlot, MLGTexture* aTexture) -{ - RefPtr view; - if (aTexture) { - MLGTextureD3D11* texture = aTexture->AsD3D11(); - view = texture->GetShaderResourceView(); - } - - ID3D11ShaderResourceView* viewPtr = view.get(); - mCtx->PSSetShaderResources(aSlot, 1, &viewPtr); -} - -void -MLGDeviceD3D11::MaybeLockTexture(ID3D11Texture2D* aTexture) -{ - RefPtr mutex; - HRESULT hr = aTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(mutex)); - if (FAILED(hr) || !mutex) { - return; - } - - hr = mutex->AcquireSync(0, 10000); - - if (hr == WAIT_TIMEOUT) { - gfxDevCrash(LogReason::D3DLockTimeout) << "D3D lock mutex timeout"; - mLockAttemptedTextures.PutEntry(mutex); - } else if (hr == WAIT_ABANDONED) { - gfxCriticalNote << "GFX: D3D11 lock mutex abandoned"; - mLockAttemptedTextures.PutEntry(mutex); - } else if (FAILED(hr)) { - gfxCriticalNote << "D3D11 lock mutex failed: " << hexa(hr); - mLockAttemptedTextures.PutEntry(mutex); - } else { - mLockedTextures.PutEntry(mutex); - } -} - -void -MLGDeviceD3D11::SetPSTexturesNV12(uint32_t aSlot, TextureSource* aTexture) -{ - MOZ_ASSERT(aTexture->GetFormat() == SurfaceFormat::NV12); - - TextureSourceD3D11* source = aTexture->AsSourceD3D11(); - if (!source) { - gfxWarning() << "Unknown texture type in SetPSCompoundTexture"; - return; - } - - ID3D11Texture2D* texture = source->GetD3D11Texture(); - if (!texture) { - gfxWarning() << "TextureSourceD3D11 does not have an ID3D11Texture"; - return; - } - - MaybeLockTexture(texture); - - RefPtr views[2]; - D3D11_SHADER_RESOURCE_VIEW_DESC desc = - CD3D11_SHADER_RESOURCE_VIEW_DESC( - D3D11_SRV_DIMENSION_TEXTURE2D, - DXGI_FORMAT_R8_UNORM); - - HRESULT hr = mDevice->CreateShaderResourceView( - texture, - &desc, - getter_AddRefs(views[0])); - if (FAILED(hr) || !views[0]) { - gfxWarning() << "Could not bind an SRV for Y plane of NV12 texture: " << hexa(hr); - return; - } - - desc.Format = DXGI_FORMAT_R8G8_UNORM; - hr = mDevice->CreateShaderResourceView( - texture, - &desc, - getter_AddRefs(views[1])); - if (FAILED(hr) || !views[0]) { - gfxWarning() << "Could not bind an SRV for CbCr plane of NV12 texture: " << hexa(hr); - return; - } - - ID3D11ShaderResourceView* bind[2] = { - views[0], - views[1] - }; - mCtx->PSSetShaderResources(aSlot, 2, bind); -} - -bool -MLGDeviceD3D11::InitSyncObject() -{ - CD3D11_TEXTURE2D_DESC desc( - DXGI_FORMAT_B8G8R8A8_UNORM, 1, 1, 1, 1, - D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET); - desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; - - RefPtr texture; - HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture)); - if (FAILED(hr) || !texture) { - return Fail("FEATURE_FAILURE_SYNC_OBJECT", - "Could not create a sync texture: %x", hr); - } - - hr = texture->QueryInterface((IDXGIResource**)getter_AddRefs(mSyncTexture)); - if (FAILED(hr) || !texture) { - return Fail("FEATURE_FAILURE_QI_SYNC_OBJECT", - "Could not QI sync texture: %x", hr); - } - - hr = mSyncTexture->GetSharedHandle(&mSyncHandle); - if (FAILED(hr) || !mSyncHandle) { - NS_DispatchToMainThread(NS_NewRunnableFunction([] () -> void { - Accumulate(Telemetry::D3D11_SYNC_HANDLE_FAILURE, 1); - })); - return Fail("FEATURE_FAILURE_GET_SHARED_HANDLE", - "Could not get sync texture shared handle: %x", hr); - } - return true; -} - -void -MLGDeviceD3D11::StartDiagnostics(uint32_t aInvalidPixels) -{ - mDiagnostics->Start(aInvalidPixels); -} - -void -MLGDeviceD3D11::EndDiagnostics() -{ - mDiagnostics->End(); -} - -void -MLGDeviceD3D11::GetDiagnostics(GPUStats* aStats) -{ - mDiagnostics->Query(aStats); -} - -bool -MLGDeviceD3D11::Synchronize() -{ - RefPtr mutex; - mSyncTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex)); - - { - HRESULT hr; - AutoTextureLock lock(mutex, hr, 10000); - if (hr == WAIT_TIMEOUT) { - hr = mDevice->GetDeviceRemovedReason(); - if (hr == S_OK) { - // There is no driver-removed event. Crash with this timeout. - MOZ_CRASH("GFX: D3D11 normal status timeout"); - } - - // Since the timeout is related to the driver-removed, clear the - // render-bounding size to skip this frame. - HandleDeviceReset("SyncObject"); - return false; - } - if (hr == WAIT_ABANDONED) { - gfxCriticalNote << "GFX: AL_D3D11 abandoned sync"; - } - } - - return true; -} - -void -MLGDeviceD3D11::UnlockAllTextures() -{ - for (auto iter = mLockedTextures.Iter(); !iter.Done(); iter.Next()) { - RefPtr mutex = iter.Get()->GetKey(); - mutex->ReleaseSync(0); - } - mLockedTextures.Clear(); - mLockAttemptedTextures.Clear(); -} - -void -MLGDeviceD3D11::SetDepthTestMode(MLGDepthTestMode aMode) -{ - mCtx->OMSetDepthStencilState(mDepthStencilStates[aMode], 0xffffffff); -} - -void -MLGDeviceD3D11::InsertPresentWaitQuery() -{ - CD3D11_QUERY_DESC desc(D3D11_QUERY_EVENT); - HRESULT hr = mDevice->CreateQuery(&desc, getter_AddRefs(mNextWaitForPresentQuery)); - if (FAILED(hr) || !mNextWaitForPresentQuery) { - gfxWarning() << "Could not create D3D11_QUERY_EVENT: " << hexa(hr); - return; - } - - mCtx->End(mNextWaitForPresentQuery); -} - -void -MLGDeviceD3D11::WaitForPreviousPresentQuery() -{ - if (mWaitForPresentQuery) { - BOOL result; - WaitForGPUQuery(mDevice, mCtx, mWaitForPresentQuery, &result); - } - mWaitForPresentQuery = mNextWaitForPresentQuery.forget(); -} - -void -MLGDeviceD3D11::Flush() -{ - mCtx->Flush(); -} - -void -MLGDeviceD3D11::EndFrame() -{ - // On our Windows 8 x64 machines, we have observed a driver bug related to - // XXSetConstantBuffers1. It appears binding the same buffer to multiple - // slots, and potentially leaving slots bound for many frames (as can - // happen if we bind a high slot, like for blending), can consistently - // cause shaders to read wrong values much later. It is possible there is - // a driver bug related to aliasing and partial binding. - // - // Configuration: GeForce GT 610 (0x104a), Driver 9.18.13.3523, 3-4-2014, - // on Windows 8 x64. - // - // To alleviate this we unbind all buffers at the end of the frame. - static ID3D11Buffer* nullBuffers[6] = { - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - }; - MOZ_ASSERT(MOZ_ARRAY_LENGTH(nullBuffers) >= kMaxVertexShaderConstantBuffers); - MOZ_ASSERT(MOZ_ARRAY_LENGTH(nullBuffers) >= kMaxPixelShaderConstantBuffers); - - mCtx->VSSetConstantBuffers(0, kMaxVertexShaderConstantBuffers, nullBuffers); - mCtx->VSSetConstantBuffers(0, kMaxPixelShaderConstantBuffers, nullBuffers); - - MLGDevice::EndFrame(); -} - -void -MLGDeviceD3D11::HandleDeviceReset(const char* aWhere) -{ - if (!IsValid()) { - return; - } - - Fail(NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_RESET"), nullptr); - - gfxCriticalNote << "GFX: D3D11 detected a device reset in " << aWhere; - if (XRE_IsGPUProcess()) { - GPUParent::GetSingleton()->NotifyDeviceReset(); - } - - UnmapSharedBuffers(); - mIsValid = false; -} - -RefPtr -MLGDeviceD3D11::CreateTexture(const gfx::IntSize& aSize, - gfx::SurfaceFormat aFormat, - MLGUsage aUsage, - MLGTextureFlags aFlags) -{ - return MLGTextureD3D11::Create(mDevice, aSize, aFormat, aUsage, aFlags); -} - -RefPtr -MLGDeviceD3D11::CreateTexture(TextureSource* aSource) -{ - TextureSourceD3D11* source = aSource->AsSourceD3D11(); - if (!source) { - gfxWarning() << "Attempted to wrap a non-D3D11 texture"; - return nullptr; - } - if (!source->GetD3D11Texture()) { - return nullptr; - } - return new MLGTextureD3D11(source->GetD3D11Texture()); -} - -void -MLGDeviceD3D11::CopyTexture(MLGTexture* aDest, - const gfx::IntPoint& aTarget, - MLGTexture* aSource, - const gfx::IntRect& aRect) -{ - MLGTextureD3D11* dest = aDest->AsD3D11(); - MLGTextureD3D11* source = aSource->AsD3D11(); - - D3D11_BOX box = RectToBox(aRect); - mCtx->CopySubresourceRegion( - dest->GetTexture(), 0, - aTarget.x, aTarget.y, 0, - source->GetTexture(), 0, - &box); -} - -static D3D11_BOX -RectToBox(const gfx::IntRect& aRect) -{ - D3D11_BOX box; - box.front = 0; - box.back = 1; - box.left = aRect.x; - box.top = aRect.y; - box.right = aRect.XMost(); - box.bottom = aRect.YMost(); - return box; -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/d3d11/MLGDeviceD3D11.h b/gfx/layers/d3d11/MLGDeviceD3D11.h deleted file mode 100644 index 5fb6504270f1..000000000000 --- a/gfx/layers/d3d11/MLGDeviceD3D11.h +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h -#define mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h - -#include "mozilla/layers/MLGDevice.h" -#include "mozilla/EnumeratedArray.h" -#include "nsTHashtable.h" -#include -#include "nsPrintfCString.h" - -namespace mozilla { -namespace layers { - -struct GPUStats; -struct ShaderBytes; -class DiagnosticsD3D11; - -class MLGRenderTargetD3D11 final : public MLGRenderTarget -{ -public: - MLGRenderTargetD3D11(const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags); - - // Create with a new texture. - bool Initialize(ID3D11Device* aDevice); - - // Do not create a texture - use the given one provided, which may be null. - // The depth buffer is still initialized. - bool Initialize(ID3D11Device* aDevice, ID3D11Texture2D* aTexture); - - gfx::IntSize GetSize() const override; - MLGRenderTargetD3D11* AsD3D11() override { return this; } - MLGTexture* GetTexture() override; - - // This is exposed only for MLGSwapChainD3D11. - bool UpdateTexture(ID3D11Texture2D* aTexture); - - ID3D11DepthStencilView* GetDSV(); - ID3D11RenderTargetView* GetRenderTargetView(); - -private: - bool CreateDepthBuffer(ID3D11Device* aDevice); - void ForgetTexture(); - -private: - ~MLGRenderTargetD3D11() override; - -private: - RefPtr mTexture; - RefPtr mRTView; - RefPtr mDepthBuffer; - RefPtr mDepthStencilView; - RefPtr mTextureSource; - gfx::IntSize mSize; -}; - -class MLGSwapChainD3D11 final : public MLGSwapChain -{ -public: - static RefPtr Create(MLGDeviceD3D11* aParent, - ID3D11Device* aDevice, - widget::CompositorWidget* aWidget); - - RefPtr AcquireBackBuffer() override; - gfx::IntSize GetSize() const override; - bool ResizeBuffers(const gfx::IntSize& aSize) override; - void CopyBackbuffer(gfx::DrawTarget* aTarget, const gfx::IntRect& aBounds) override; - void Present() override; - void ForcePresent() override; - void Destroy() override; - -private: - MLGSwapChainD3D11(MLGDeviceD3D11* aParent, ID3D11Device* aDevice); - ~MLGSwapChainD3D11() override; - - bool Initialize(widget::CompositorWidget* aWidget); - void UpdateBackBufferContents(ID3D11Texture2D* aBack); - -private: - RefPtr mParent; - RefPtr mDevice; - RefPtr mSwapChain; - RefPtr mSwapChain1; - RefPtr mRT; - widget::CompositorWidget* mWidget; - gfx::IntSize mSize; - bool mCanUsePartialPresents; -}; - -class MLGResourceD3D11 -{ -public: - virtual ID3D11Resource* GetResource() const = 0; -}; - -class MLGBufferD3D11 final : public MLGBuffer, public MLGResourceD3D11 -{ -public: - static RefPtr Create( - ID3D11Device* aDevice, - MLGBufferType aType, - uint32_t aSize, - MLGUsage aUsage, - const void* aInitialData); - - MLGBufferD3D11* AsD3D11() override { - return this; - } - ID3D11Resource* GetResource() const override { - return mBuffer; - } - ID3D11Buffer* GetBuffer() const { - return mBuffer; - } - MLGResourceD3D11* AsResourceD3D11() override { - return this; - } - size_t GetSize() const override { - return mSize; - } - -protected: - MLGBufferD3D11(ID3D11Buffer* aBuffer, MLGBufferType aType, size_t aSize); - ~MLGBufferD3D11() override; - -private: - RefPtr mBuffer; - MLGBufferType mType; - size_t mSize; -}; - -class MLGTextureD3D11 final : public MLGTexture, public MLGResourceD3D11 -{ -public: - explicit MLGTextureD3D11(ID3D11Texture2D* aTexture); - - static RefPtr Create( - ID3D11Device* aDevice, - const gfx::IntSize& aSize, - gfx::SurfaceFormat aFormat, - MLGUsage aUsage, - MLGTextureFlags aFlags); - - MLGTextureD3D11* AsD3D11() override { - return this; - } - MLGResourceD3D11* AsResourceD3D11() override { - return this; - } - ID3D11Texture2D* GetTexture() const { - return mTexture; - } - ID3D11Resource* GetResource() const override { - return mTexture; - } - ID3D11ShaderResourceView* GetShaderResourceView(); - -private: - RefPtr mTexture; - RefPtr mView; -}; - -class MLGDeviceD3D11 final : public MLGDevice -{ -public: - explicit MLGDeviceD3D11(ID3D11Device* aDevice); - ~MLGDeviceD3D11() override; - - bool Initialize() override; - - void StartDiagnostics(uint32_t aInvalidPixels) override; - void EndDiagnostics() override; - void GetDiagnostics(GPUStats* aStats) override; - - MLGDeviceD3D11* AsD3D11() override { return this; } - TextureFactoryIdentifier GetTextureFactoryIdentifier() const override; - - RefPtr CreateSwapChainForWidget(widget::CompositorWidget* aWidget) override; - - int32_t GetMaxTextureSize() const override; - LayersBackend GetLayersBackend() const override; - - void EndFrame() override; - - bool Map(MLGResource* aResource, MLGMapType aType, MLGMappedResource* aMap) override; - void Unmap(MLGResource* aResource) override; - void UpdatePartialResource( - MLGResource* aResource, - const gfx::IntRect* aRect, - void* aData, - uint32_t aStride) override; - void CopyTexture(MLGTexture* aDest, - const gfx::IntPoint& aTarget, - MLGTexture* aSource, - const gfx::IntRect& aRect) override; - - RefPtr CreateDataTextureSource(TextureFlags aFlags) override; - - void SetRenderTarget(MLGRenderTarget* aRT) override; - MLGRenderTarget* GetRenderTarget() override; - void SetViewport(const gfx::IntRect& aViewport) override; - void SetScissorRect(const Maybe& aScissorRect) override; - void SetVertexShader(VertexShaderID aVertexShader) override; - void SetPixelShader(PixelShaderID aPixelShader) override; - void SetSamplerMode(uint32_t aIndex, SamplerMode aSamplerMode) override; - void SetBlendState(MLGBlendState aBlendState) override; - void SetVertexBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aStride, uint32_t aOffset) override; - void SetPSTextures(uint32_t aSlot, uint32_t aNumTextures, TextureSource* const* aTextures) override; - void SetPSTexture(uint32_t aSlot, MLGTexture* aTexture) override; - void SetPSTexturesNV12(uint32_t aSlot, TextureSource* aTexture) override; - void SetPrimitiveTopology(MLGPrimitiveTopology aTopology) override; - void SetDepthTestMode(MLGDepthTestMode aMode) override; - - void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) override; - void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) override; - void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aFirstConstant, uint32_t aNumConstants) override; - void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aFirstConstant, uint32_t aNumConstants) override; - - RefPtr CreateBuffer( - MLGBufferType aType, - uint32_t aSize, - MLGUsage aUsage, - const void* aInitialData) override; - - RefPtr CreateRenderTarget( - const gfx::IntSize& aSize, - MLGRenderTargetFlags aFlags) override; - - RefPtr CreateTexture( - const gfx::IntSize& aSize, - gfx::SurfaceFormat aFormat, - MLGUsage aUsage, - MLGTextureFlags aFlags) override; - - RefPtr CreateTexture(TextureSource* aSource) override; - - void Clear(MLGRenderTarget* aRT, const gfx::Color& aColor) override; - void ClearDepthBuffer(MLGRenderTarget* aRT) override; - void ClearView(MLGRenderTarget* aRT, const gfx::Color& aColor, const gfx::IntRect* aRects, size_t aNumRects) override; - void Draw(uint32_t aVertexCount, uint32_t aOffset) override; - void DrawInstanced(uint32_t aVertexCountPerInstance, uint32_t aInstanceCount, - uint32_t aVertexOffset, uint32_t aInstanceOffset) override; - void Flush() override; - - // This is exposed for TextureSourceProvider. - ID3D11Device* GetD3D11Device() const { - return mDevice; - } - - bool Synchronize() override; - void UnlockAllTextures() override; - - void InsertPresentWaitQuery(); - void WaitForPreviousPresentQuery(); - void HandleDeviceReset(const char* aWhere); - -private: - bool InitSyncObject(); - - void MaybeLockTexture(ID3D11Texture2D* aTexture); - - bool InitPixelShader(PixelShaderID aShaderID); - bool InitVertexShader(VertexShaderID aShaderID); - bool InitInputLayout(D3D11_INPUT_ELEMENT_DESC* aDesc, - size_t aNumElements, - const ShaderBytes& aCode, - VertexShaderID aShaderID); - bool InitRasterizerStates(); - bool InitSamplerStates(); - bool InitBlendStates(); - bool InitDepthStencilState(); - -private: - RefPtr mDevice; - RefPtr mCtx; - RefPtr mCtx1; - UniquePtr mDiagnostics; - - typedef EnumeratedArray> PixelShaderArray; - typedef EnumeratedArray> VertexShaderArray; - typedef EnumeratedArray> InputLayoutArray; - typedef EnumeratedArray> SamplerStateArray; - typedef EnumeratedArray> BlendStateArray; - typedef EnumeratedArray> DepthStencilStateArray; - - PixelShaderArray mPixelShaders; - VertexShaderArray mVertexShaders; - InputLayoutArray mInputLayouts; - SamplerStateArray mSamplerStates; - BlendStateArray mBlendStates; - DepthStencilStateArray mDepthStencilStates; - RefPtr mRasterizerStateNoScissor; - RefPtr mRasterizerStateScissor; - - RefPtr mSyncTexture; - HANDLE mSyncHandle; - - RefPtr mCurrentRT; - RefPtr mUnitQuadVB; - RefPtr mCurrentVertexShader; - RefPtr mCurrentInputLayout; - RefPtr mCurrentPixelShader; - RefPtr mCurrentBlendState; - - RefPtr mWaitForPresentQuery; - RefPtr mNextWaitForPresentQuery; - - nsTHashtable> mLockedTextures; - nsTHashtable> mLockAttemptedTextures; - - typedef EnumeratedArray LazyPixelShaderArray; - LazyPixelShaderArray mLazyPixelShaders; - - typedef EnumeratedArray LazyVertexShaderArray; - LazyVertexShaderArray mLazyVertexShaders; - - bool mScissored; -}; - -} // namespace layers -} // namespace mozilla - -struct ShaderBytes; - -#endif // mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index 680ca4f7e65d..ed60bcd3bec9 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -90,14 +90,6 @@ SurfaceFormatToDXGIFormat(gfx::SurfaceFormat aFormat) } } -void -ReportTextureMemoryUsage(ID3D11Texture2D* aTexture, size_t aBytes) -{ - aTexture->SetPrivateDataInterface( - sD3D11TextureUsage, - new TextureMemoryMeasurer(aBytes)); -} - static uint32_t GetRequiredTilesD3D11(uint32_t aSize, uint32_t aMaxSize) { diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index 783397e45b4a..1c4bb0936d64 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -483,7 +483,6 @@ inline uint32_t GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel } uint32_t GetMaxTextureSizeFromDevice(ID3D11Device* aDevice); -void ReportTextureMemoryUsage(ID3D11Texture2D* aTexture, size_t aBytes); class AutoLockD3D11Texture { diff --git a/gfx/layers/d3d11/mlgshaders/blend-common.hlsl b/gfx/layers/d3d11/mlgshaders/blend-common.hlsl deleted file mode 100644 index 1194fc080102..000000000000 --- a/gfx/layers/d3d11/mlgshaders/blend-common.hlsl +++ /dev/null @@ -1,15 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-vs.hlsl" - -struct VS_BLEND_OUTPUT -{ - float4 vPosition : SV_Position; - float2 vTexCoords : TEXCOORD0; - float2 vBackdropCoords : TEXCOORD1; - float2 vLocalPos : TEXCOORD2; - float3 vMaskCoords : TEXCOORD3; - nointerpolation float4 vClipRect : TEXCOORD4; -}; diff --git a/gfx/layers/d3d11/mlgshaders/blend-ps-generated.hlslh b/gfx/layers/d3d11/mlgshaders/blend-ps-generated.hlslh deleted file mode 100644 index 655f3e0cb428..000000000000 --- a/gfx/layers/d3d11/mlgshaders/blend-ps-generated.hlslh +++ /dev/null @@ -1,540 +0,0 @@ -float4 BlendMultiplyPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendMultiply(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendScreenPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendScreen(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendOverlayPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendOverlay(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendDarkenPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendDarken(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendLightenPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendLighten(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendColorDodgePS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendColorDodge(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendColorBurnPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendColorBurn(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendHardLightPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= sOpacity; - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendHardLight(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendSoftLightPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendSoftLight(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendDifferencePS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendDifference(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendExclusionPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendExclusion(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendHuePS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendHue(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendSaturationPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendSaturation(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendColorPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendColor(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - -float4 BlendLuminosityPS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = BlendLuminosity(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} - diff --git a/gfx/layers/d3d11/mlgshaders/blend-ps-generated.hlslh.tpl b/gfx/layers/d3d11/mlgshaders/blend-ps-generated.hlslh.tpl deleted file mode 100644 index a24577a09ad4..000000000000 --- a/gfx/layers/d3d11/mlgshaders/blend-ps-generated.hlslh.tpl +++ /dev/null @@ -1,36 +0,0 @@ -float4 Blend{BLEND_FUNC}PS(const VS_BLEND_OUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - discard; - } - - float4 backdrop = tBackdrop.Sample(sSampler, aInput.vBackdropCoords); - float4 source = simpleTex.Sample(sSampler, aInput.vTexCoords); - - // Apply masks to the source texture, not the result. - source *= ReadMask(aInput.vMaskCoords); - - // Shortcut when the backdrop or source alpha is 0, otherwise we may leak - // infinity into the blend function and return incorrect results. - if (backdrop.a == 0.0) { - return source; - } - if (source.a == 0.0) { - return float4(0, 0, 0, 0); - } - - // The spec assumes there is no premultiplied alpha. The backdrop and - // source are both render targets and always premultiplied, so we undo - // that here. - backdrop.rgb /= backdrop.a; - source.rgb /= source.a; - - float4 result; - result.rgb = Blend{BLEND_FUNC}(backdrop.rgb, source.rgb); - result.a = source.a; - - // Factor backdrop alpha, then premultiply for the final OP_OVER. - result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb; - result.rgb *= result.a; - return result; -} diff --git a/gfx/layers/d3d11/mlgshaders/blend-ps.hlsl b/gfx/layers/d3d11/mlgshaders/blend-ps.hlsl deleted file mode 100644 index 094bfdfdb138..000000000000 --- a/gfx/layers/d3d11/mlgshaders/blend-ps.hlsl +++ /dev/null @@ -1,13 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common.hlsl" -#include "common-ps.hlsl" -#include "blend-common.hlsl" -#include "../BlendingHelpers.hlslh" - -Texture2D simpleTex : register(ps, t0); -Texture2D tBackdrop : register(ps, t1); - -#include "blend-ps-generated.hlslh" diff --git a/gfx/layers/d3d11/mlgshaders/blend-vs.hlsl b/gfx/layers/d3d11/mlgshaders/blend-vs.hlsl deleted file mode 100644 index 0ab437492c3c..000000000000 --- a/gfx/layers/d3d11/mlgshaders/blend-vs.hlsl +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-vs.hlsl" -#include "blend-common.hlsl" -#include "textured-common.hlsl" - -cbuffer BlendConstants : register(b4) -{ - float4x4 mBackdropTransform; -} - -float2 BackdropPosition(float4 aPosition) -{ - // Move the position from clip space (-1,1) into 0..1 space. - float2 pos; - pos.x = (aPosition.x + 1.0) / 2.0; - pos.y = 1.0 - (aPosition.y + 1.0) / 2.0; - - return mul(mBackdropTransform, float4(pos.xy, 0, 1.0)).xy; -} - -VS_BLEND_OUTPUT BlendImpl(const VertexInfo aInfo, float2 aTexCoord) -{ - VS_BLEND_OUTPUT output; - output.vPosition = aInfo.worldPos; - output.vTexCoords = aTexCoord; - output.vBackdropCoords = BackdropPosition(output.vPosition); - output.vLocalPos = aInfo.screenPos; - output.vClipRect = aInfo.clipRect; - output.vMaskCoords = aInfo.maskCoords; - return output; -} - -VS_BLEND_OUTPUT BlendVertexVS(const VS_TEXTUREDVERTEX aVertex) -{ - VertexInfo info = ComputePosition(aVertex.vLayerPos, aVertex.vLayerId, aVertex.vDepth); - - return BlendImpl(info, aVertex.vTexCoord); -} diff --git a/gfx/layers/d3d11/mlgshaders/clear-common.hlsl b/gfx/layers/d3d11/mlgshaders/clear-common.hlsl deleted file mode 100644 index da69301d3482..000000000000 --- a/gfx/layers/d3d11/mlgshaders/clear-common.hlsl +++ /dev/null @@ -1,9 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -struct VS_CLEAR_OUT -{ - float4 vPosition : SV_Position; -}; diff --git a/gfx/layers/d3d11/mlgshaders/clear-ps.hlsl b/gfx/layers/d3d11/mlgshaders/clear-ps.hlsl deleted file mode 100644 index 7313585eed7c..000000000000 --- a/gfx/layers/d3d11/mlgshaders/clear-ps.hlsl +++ /dev/null @@ -1,12 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-ps.hlsl" -#include "clear-common.hlsl" - -float4 ClearPS(const VS_CLEAR_OUT aVS) : SV_Target -{ - return float4(0.0, 0.0, 0.0, 0.0); -} - diff --git a/gfx/layers/d3d11/mlgshaders/clear-vs.hlsl b/gfx/layers/d3d11/mlgshaders/clear-vs.hlsl deleted file mode 100644 index 5d95fcf61187..000000000000 --- a/gfx/layers/d3d11/mlgshaders/clear-vs.hlsl +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-vs.hlsl" -#include "clear-common.hlsl" - -struct VS_CLEAR_IN -{ - float2 vPos : POSITION; - int4 vRect : TEXCOORD0; -}; - -// Note: we use slot 2 so we don't have to rebind the layer slot (1) to run -// this shader. -cbuffer ClearConstants : register(b2) { - int sDepth : packoffset(c0.x); -}; - -VS_CLEAR_OUT ClearVS(const VS_CLEAR_IN aInput) -{ - float4 rect = float4(aInput.vRect.x, aInput.vRect.y, aInput.vRect.z, aInput.vRect.w); - float4 screenPos = float4(UnitQuadToRect(aInput.vPos, rect), 0, 1); - float4 worldPos = mul(WorldTransform, screenPos); - worldPos.z = ComputeDepth(worldPos, sDepth); - - VS_CLEAR_OUT output; - output.vPosition = worldPos; - return output; -} diff --git a/gfx/layers/d3d11/mlgshaders/color-common.hlsl b/gfx/layers/d3d11/mlgshaders/color-common.hlsl deleted file mode 100644 index 1769cbed80ee..000000000000 --- a/gfx/layers/d3d11/mlgshaders/color-common.hlsl +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -struct VS_COLOROUTPUT -{ - nointerpolation float4 vColor : COLOR0; - nointerpolation float4 vClipRect : TEXCOORD0; - float4 vPosition : SV_Position; - float2 vLocalPos : TEXCOORD1; - float3 vMaskCoords : TEXCOORD2; -}; - -struct VS_COLOROUTPUT_CLIPPED -{ - float4 vPosition : SV_Position; - nointerpolation float4 vColor : COLOR0; -}; diff --git a/gfx/layers/d3d11/mlgshaders/color-ps.hlsl b/gfx/layers/d3d11/mlgshaders/color-ps.hlsl deleted file mode 100644 index 4bbd54559427..000000000000 --- a/gfx/layers/d3d11/mlgshaders/color-ps.hlsl +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-ps.hlsl" -#include "color-common.hlsl" - -float4 ColoredQuadPS(const VS_COLOROUTPUT_CLIPPED aVS) : SV_Target -{ - // Opacity is always 1.0, we premultiply it on the CPU. - return aVS.vColor; -} - -float4 ColoredVertexPS(const VS_COLOROUTPUT aVS) : SV_Target -{ - if (!RectContainsPoint(aVS.vClipRect, aVS.vPosition.xy)) { - return float4(0, 0, 0, 0); - } - return aVS.vColor * ReadMaskWithOpacity(aVS.vMaskCoords, 1.0); -} diff --git a/gfx/layers/d3d11/mlgshaders/color-vs.hlsl b/gfx/layers/d3d11/mlgshaders/color-vs.hlsl deleted file mode 100644 index 33da54ab7f74..000000000000 --- a/gfx/layers/d3d11/mlgshaders/color-vs.hlsl +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-vs.hlsl" -#include "color-common.hlsl" - -struct ColorItem -{ - float4 color; -}; -#define SIZEOF_COLORITEM 1 - -ColorItem GetItem(uint aIndex) -{ - uint offset = aIndex * SIZEOF_COLORITEM; - ColorItem item; - item.color = sItems[offset + 0]; - return item; -} - -struct VS_COLORQUAD -{ - float2 vPos : POSITION; - float4 vRect : TEXCOORD0; - uint vLayerId : TEXCOORD1; - int vDepth : TEXCOORD2; - uint vIndex : SV_InstanceID; -}; - -struct VS_COLORVERTEX -{ - float2 vLayerPos : POSITION; - uint vLayerId : TEXCOORD0; - int vDepth : TEXCOORD1; - uint vIndex : TEXCOORD2; -}; - -VS_COLOROUTPUT ColorImpl(float4 aColor, const VertexInfo aInfo) -{ - VS_COLOROUTPUT output; - output.vPosition = aInfo.worldPos; - output.vLocalPos = aInfo.screenPos; - output.vColor = aColor; - output.vClipRect = aInfo.clipRect; - output.vMaskCoords = aInfo.maskCoords; - return output; -} - -VS_COLOROUTPUT_CLIPPED ColoredQuadVS(const VS_COLORQUAD aInput) -{ - ColorItem item = GetItem(aInput.vIndex); - float4 worldPos = ComputeClippedPosition( - aInput.vPos, - aInput.vRect, - aInput.vLayerId, - aInput.vDepth); - - VS_COLOROUTPUT_CLIPPED output; - output.vPosition = worldPos; - output.vColor = item.color; - return output; -} - -VS_COLOROUTPUT ColoredVertexVS(const VS_COLORVERTEX aInput) -{ - ColorItem item = GetItem(aInput.vIndex); - VertexInfo info = ComputePosition(aInput.vLayerPos, aInput.vLayerId, aInput.vDepth); - return ColorImpl(item.color, info); -} diff --git a/gfx/layers/d3d11/mlgshaders/common-ps.hlsl b/gfx/layers/d3d11/mlgshaders/common-ps.hlsl deleted file mode 100644 index 624f87e2ce89..000000000000 --- a/gfx/layers/d3d11/mlgshaders/common-ps.hlsl +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common.hlsl" - -sampler sSampler : register(ps, s0); -sampler sMaskSampler : register(ps, s1); - -Texture2D tMaskTexture : register(ps, t4); - -cbuffer MaskInformation : register(b0) -{ - float sOpacity : packoffset(c0.x); - uint sHasMask : packoffset(c0.y); -}; - -float2 MaskCoordsToUV(float3 aMaskCoords) -{ - return aMaskCoords.xy / aMaskCoords.z; -} - -float ReadMaskWithOpacity(float3 aMaskCoords, float aOpacity) -{ - if (!sHasMask) { - return aOpacity; - } - - float2 uv = MaskCoordsToUV(aMaskCoords); - float r = tMaskTexture.Sample(sMaskSampler, uv).r; - return min(aOpacity, r); -} - -float ReadMask(float3 aMaskCoords) -{ - return ReadMaskWithOpacity(aMaskCoords, sOpacity); -} diff --git a/gfx/layers/d3d11/mlgshaders/common-vs.hlsl b/gfx/layers/d3d11/mlgshaders/common-vs.hlsl deleted file mode 100644 index 4befa7b50953..000000000000 --- a/gfx/layers/d3d11/mlgshaders/common-vs.hlsl +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_d3d11_mlgshaders_common_vs_hlsl -#define mozilla_gfx_layers_d3d11_mlgshaders_common_vs_hlsl - -#include "common.hlsl" - -cbuffer VSBufSimple : register(b0) -{ - float4x4 WorldTransform; - float2 RenderTargetOffset; - int SortIndexOffset; - float padding; -}; - -struct Layer { - float4x4 transform; - float4 clipRect; - uint4 info; -}; - -cbuffer Layers : register(b1) -{ - Layer sLayers[682]; -}; - -cbuffer Items : register(b2) -{ - float4 sItems[4096]; -}; - -cbuffer MaskRects : register(b3) -{ - float4 sMaskRects[4096]; -}; - -struct VertexInfo { - float4 worldPos; - float2 screenPos; - float3 maskCoords; - float4 clipRect; -}; - -float3 ComputeMaskCoords(float4 aPosition, Layer aLayer) -{ - if (aLayer.info.x == 0) { - return float3(0.0, 0.0, 0.0); - } - - float4 maskRect = sMaskRects[aLayer.info.x - 1]; - - // See the perspective comment in CompositorD3D11.hlsl. - float4x4 transform = float4x4( - 1.0/maskRect.z, 0.0, 0.0, -maskRect.x/maskRect.z, - 0.0, 1.0/maskRect.w, 0.0, -maskRect.y/maskRect.w, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0); - - return float3(mul(transform, aPosition / aPosition.w).xy, 1.0) * aPosition.w; -} - -float2 UnitQuadToRect(const float2 aVertex, const float4 aRect) -{ - return float2(aRect.x + aVertex.x * aRect.z, aRect.y + aVertex.y * aRect.w); -} - -float ComputeDepth(float4 aPosition, float aSortIndex) -{ - // Note: this value should match ShaderDefinitionsMLGPU.h. - return ((aSortIndex + SortIndexOffset) / 1000000.0f) * aPosition.w; -} - -// Compute the world-space, screen-space, layer-space clip, and mask -// uv-coordinates given a layer-space vertex, id, and z-index. -VertexInfo ComputePosition(float2 aVertex, uint aLayerId, float aSortIndex) -{ - Layer layer = sLayers[aLayerId]; - - // Translate from unit vertex to layer quad vertex. - float4 position = float4(aVertex, 0, 1); - float4 clipRect = layer.clipRect; - - // Transform to screen coordinates. - float4x4 transform = layer.transform; - position = mul(transform, position); - position.xyz /= position.w; - position.xy -= RenderTargetOffset.xy; - position.xyz *= position.w; - - float4 worldPos = mul(WorldTransform, position); - - // Depth must be computed after the world transform, since we don't want - // 3d transforms clobbering the z-value. We assume a viewport culling - // everything outside of [0, 1). Note that when depth-testing, we do not - // use sorting indices < 1. - // - // Note that we have to normalize this value to w=1, since the GPU will - // divide all values by w internally. - worldPos.z = ComputeDepth(worldPos, aSortIndex); - - VertexInfo info; - info.screenPos = position.xy; - info.worldPos = worldPos; - info.maskCoords = ComputeMaskCoords(position, layer); - info.clipRect = clipRect; - return info; -} - -// This function takes a unit quad position and a layer rectangle, and computes -// a clipped draw rect. It is only valid to use this function for layers with -// rectilinear transforms that do not have masks. -float4 ComputeClippedPosition(const float2 aVertex, - const float4 aRect, - uint aLayerId, - float aDepth) -{ - Layer layer = sLayers[aLayerId]; - - float4 position = float4(UnitQuadToRect(aVertex, aRect), 0, 1); - - float4x4 transform = layer.transform; - float4 clipRect = layer.clipRect; - - // Transform to screen coordinates. - // - // We clamp the draw rect to the clip. This lets us use faster shaders. - // For opaque shapes, it is necessary to do this anyway since we might - // otherwrite write transparent pixels in the pixel which would also be - // written to the depth buffer. We cannot use discard in the pixel shader - // as this would break early-z tests. - // - // Note that for some shaders, like textured shaders, it is not valid to - // change the draw rect like this without also clamping the texture - // coordinates. We take care to adjust for this in our batching code. - // - // We do not need to do this for 3D transforms since we always treat those - // as transparent (they are not written to the depth buffer). 3D items - // will always use the full clip+masking shader. - position = mul(transform, position); - position.xyz /= position.w; - position.xy -= RenderTargetOffset.xy; - position.xy = clamp(position.xy, clipRect.xy, clipRect.xy + clipRect.zw); - position.xyz *= position.w; - - float4 worldPos = mul(WorldTransform, position); - - // Depth must be computed after the world transform, since we don't want - // 3d transforms clobbering the z-value. We assume a viewport culling - // everything outside of [0, 1). Note that when depth-testing, we do not - // use sorting indices < 1. - // - // Note that we have to normalize this value to w=1, since the GPU will - // divide all values by w internally. - worldPos.z = ComputeDepth(worldPos, aDepth); - - return worldPos; -} - -#endif // mozilla_gfx_layers_d3d11_mlgshaders_common_vs_hlsl diff --git a/gfx/layers/d3d11/mlgshaders/common.hlsl b/gfx/layers/d3d11/mlgshaders/common.hlsl deleted file mode 100644 index 8c51370d0850..000000000000 --- a/gfx/layers/d3d11/mlgshaders/common.hlsl +++ /dev/null @@ -1,17 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_d3d11_mlgshaders_common_hlsl -#define mozilla_gfx_layers_d3d11_mlgshaders_common_hlsl - -bool RectContainsPoint(float4 aRect, float2 aPoint) -{ - return aPoint.x >= aRect.x && - aPoint.y >= aRect.y && - aPoint.x <= (aRect.x + aRect.z) && - aPoint.y <= (aRect.y + aRect.w); -} - -#endif // mozilla_gfx_layers_d3d11_mlgshaders_common_hlsl diff --git a/gfx/layers/d3d11/mlgshaders/component-alpha-ps.hlsl b/gfx/layers/d3d11/mlgshaders/component-alpha-ps.hlsl deleted file mode 100644 index d1705dd1b9cc..000000000000 --- a/gfx/layers/d3d11/mlgshaders/component-alpha-ps.hlsl +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common.hlsl" -#include "common-ps.hlsl" -#include "textured-common.hlsl" - -Texture2D texOnBlack : register(ps, t0); -Texture2D texOnWhite : register(ps, t1); - -struct PS_OUTPUT { - float4 vSrc; - float4 vAlpha; -}; - -PS_OUTPUT ComponentAlphaQuadPS(const VS_SAMPLEOUTPUT_CLIPPED aInput) : SV_Target -{ - PS_OUTPUT result; - result.vSrc = texOnBlack.Sample(sSampler, aInput.vTexCoords); - result.vAlpha = 1.0 - texOnWhite.Sample(sSampler, aInput.vTexCoords) + result.vSrc; - result.vSrc.a = result.vAlpha.g; - result.vSrc *= sOpacity; - result.vAlpha *= sOpacity; - return result; -} - -PS_OUTPUT ComponentAlphaVertexPS(const VS_SAMPLEOUTPUT aInput) : SV_Target -{ - PS_OUTPUT result; - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - result.vSrc = float4(0, 0, 0, 0); - result.vAlpha = float4(0, 0, 0, 0); - return result; - } - - float alpha = ReadMask(aInput.vMaskCoords); - - result.vSrc = texOnBlack.Sample(sSampler, aInput.vTexCoords); - result.vAlpha = 1.0 - texOnWhite.Sample(sSampler, aInput.vTexCoords) + result.vSrc; - result.vSrc.a = result.vAlpha.g; - result.vSrc *= alpha; - result.vAlpha *= alpha; - return result; -} diff --git a/gfx/layers/d3d11/mlgshaders/diagnostics-common.hlsl b/gfx/layers/d3d11/mlgshaders/diagnostics-common.hlsl deleted file mode 100644 index 49ddcb3d99d8..000000000000 --- a/gfx/layers/d3d11/mlgshaders/diagnostics-common.hlsl +++ /dev/null @@ -1,10 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -struct VS_DIAGOUTPUT -{ - float4 vPosition : SV_Position; - float2 vTexCoord : TEXCOORD0; -}; diff --git a/gfx/layers/d3d11/mlgshaders/diagnostics-ps.hlsl b/gfx/layers/d3d11/mlgshaders/diagnostics-ps.hlsl deleted file mode 100644 index 893e5e19b489..000000000000 --- a/gfx/layers/d3d11/mlgshaders/diagnostics-ps.hlsl +++ /dev/null @@ -1,13 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-ps.hlsl" -#include "diagnostics-common.hlsl" - -Texture2D sTexture: register(ps, t0); - -float4 DiagnosticTextPS(const VS_DIAGOUTPUT aInput) : SV_Target -{ - return sTexture.Sample(sSampler, aInput.vTexCoord); -} diff --git a/gfx/layers/d3d11/mlgshaders/diagnostics-vs.hlsl b/gfx/layers/d3d11/mlgshaders/diagnostics-vs.hlsl deleted file mode 100644 index e240b3c374c0..000000000000 --- a/gfx/layers/d3d11/mlgshaders/diagnostics-vs.hlsl +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-vs.hlsl" -#include "textured-common.hlsl" -#include "diagnostics-common.hlsl" - -struct VS_DIAGINPUT -{ - float2 vPos : POSITION; - float4 vRect : TEXCOORD0; - float4 vTexCoords : TEXCOORD1; -}; - -VS_DIAGOUTPUT DiagnosticTextVS(const VS_DIAGINPUT aInput) -{ - float2 pos = UnitQuadToRect(aInput.vPos, aInput.vRect); - float2 texCoord = UnitQuadToRect(aInput.vPos, aInput.vTexCoords); - - VS_DIAGOUTPUT output; - output.vPosition = mul(WorldTransform, float4(pos, 0, 1)); - output.vTexCoord = texCoord; - return output; -} diff --git a/gfx/layers/d3d11/mlgshaders/mask-combiner-common.hlsl b/gfx/layers/d3d11/mlgshaders/mask-combiner-common.hlsl deleted file mode 100644 index a1201f783363..000000000000 --- a/gfx/layers/d3d11/mlgshaders/mask-combiner-common.hlsl +++ /dev/null @@ -1,10 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -struct VS_MASKOUTPUT -{ - float4 vPosition : SV_Position; - float2 vTexCoords : TEXCOORD0; -}; diff --git a/gfx/layers/d3d11/mlgshaders/mask-combiner-ps.hlsl b/gfx/layers/d3d11/mlgshaders/mask-combiner-ps.hlsl deleted file mode 100644 index 35010aed6f89..000000000000 --- a/gfx/layers/d3d11/mlgshaders/mask-combiner-ps.hlsl +++ /dev/null @@ -1,16 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common.hlsl" -#include "mask-combiner-common.hlsl" - -sampler sSampler; - -Texture2D tMaskTexture : register(ps, t0); - -float4 MaskCombinerPS(VS_MASKOUTPUT aInput) : SV_Target -{ - float4 value = tMaskTexture.Sample(sSampler, aInput.vTexCoords); - return float4(value.r, 0, 0, value.r); -} diff --git a/gfx/layers/d3d11/mlgshaders/mask-combiner-vs.hlsl b/gfx/layers/d3d11/mlgshaders/mask-combiner-vs.hlsl deleted file mode 100644 index 7db1d5edca1d..000000000000 --- a/gfx/layers/d3d11/mlgshaders/mask-combiner-vs.hlsl +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-vs.hlsl" -#include "mask-combiner-common.hlsl" - -struct VS_MASKINPUT -{ - // Note, the input is - float2 vPos : POSITION; - float4 vTexCoords : POSITION1; -}; - -VS_MASKOUTPUT MaskCombinerVS(VS_MASKINPUT aInput) -{ - float4 position = float4( - aInput.vPos.x * 2.0f - 1.0f, - 1.0f - (aInput.vPos.y * 2.0f), - 0, 1); - - VS_MASKOUTPUT output; - output.vPosition = position; - output.vTexCoords = UnitQuadToRect(aInput.vPos, aInput.vTexCoords); - return output; -} diff --git a/gfx/layers/d3d11/mlgshaders/shaders.manifest b/gfx/layers/d3d11/mlgshaders/shaders.manifest deleted file mode 100644 index b8b206183d5b..000000000000 --- a/gfx/layers/d3d11/mlgshaders/shaders.manifest +++ /dev/null @@ -1,94 +0,0 @@ -- type: vs_4_0 - file: textured-vs.hlsl - shaders: - - TexturedQuadVS - - TexturedVertexVS - -- type: ps_4_0 - file: textured-ps.hlsl - shaders: - - TexturedVertexRGB - - TexturedVertexRGBA - - TexturedQuadRGB - - TexturedQuadRGBA - -- type: ps_4_0 - file: ycbcr-ps.hlsl - shaders: - - TexturedVertexIMC4 - - TexturedVertexNV12 - - TexturedQuadIMC4 - - TexturedQuadNV12 - -- type: vs_4_0 - file: color-vs.hlsl - shaders: - - ColoredQuadVS - - ColoredVertexVS - -- type: ps_4_0 - file: color-ps.hlsl - shaders: - - ColoredQuadPS - - ColoredVertexPS - -- type: ps_4_0 - file: component-alpha-ps.hlsl - shaders: - - ComponentAlphaQuadPS - - ComponentAlphaVertexPS - -- type: vs_4_0 - file: blend-vs.hlsl - shaders: - - BlendVertexVS - -- type: ps_4_0 - file: blend-ps.hlsl - shaders: - - BlendMultiplyPS - - BlendScreenPS - - BlendOverlayPS - - BlendDarkenPS - - BlendLightenPS - - BlendColorDodgePS - - BlendColorBurnPS - - BlendHardLightPS - - BlendSoftLightPS - - BlendDifferencePS - - BlendExclusionPS - - BlendHuePS - - BlendSaturationPS - - BlendColorPS - - BlendLuminosityPS - -- type: vs_4_0 - file: clear-vs.hlsl - shaders: - - ClearVS - -- type: ps_4_0 - file: clear-ps.hlsl - shaders: - - ClearPS - -- type: vs_4_0 - file: mask-combiner-vs.hlsl - shaders: - - MaskCombinerVS - -- type: ps_4_0 - file: mask-combiner-ps.hlsl - shaders: - - MaskCombinerPS - -- type: vs_4_0 - file: diagnostics-vs.hlsl - shaders: - - DiagnosticTextVS - -- type: ps_4_0 - file: diagnostics-ps.hlsl - shaders: - - DiagnosticTextPS - diff --git a/gfx/layers/d3d11/mlgshaders/textured-common.hlsl b/gfx/layers/d3d11/mlgshaders/textured-common.hlsl deleted file mode 100644 index 0ec94128fabe..000000000000 --- a/gfx/layers/d3d11/mlgshaders/textured-common.hlsl +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef VERTEX_SHADER -struct TexturedItem -{ - float4 texCoords; -}; -#define SIZEOF_TEXTUREDITEM 1 - -TexturedItem GetItem(uint aIndex) -{ - uint offset = aIndex * SIZEOF_TEXTUREDITEM; - TexturedItem item; - item.texCoords = sItems[offset + 0]; - return item; -} -#endif - -// Instanced version. -struct VS_TEXTUREDINPUT -{ - float2 vPos : POSITION; - float4 vRect : TEXCOORD0; - uint vLayerId : TEXCOORD1; - int vDepth : TEXCOORD2; - uint vIndex : SV_InstanceID; -}; - -// Non-instanced version. -struct VS_TEXTUREDVERTEX -{ - float2 vLayerPos : POSITION; - float2 vTexCoord : TEXCOORD0; - uint vLayerId : TEXCOORD1; - int vDepth : TEXCOORD2; -}; - -struct VS_SAMPLEOUTPUT -{ - float4 vPosition : SV_Position; - float2 vTexCoords : TEXCOORD0; - float2 vLocalPos : TEXCOORD1; - float3 vMaskCoords : TEXCOORD2; - nointerpolation float4 vClipRect : TEXCOORD3; -}; - -struct VS_SAMPLEOUTPUT_CLIPPED -{ - float4 vPosition : SV_Position; - float2 vTexCoords : TEXCOORD0; -}; diff --git a/gfx/layers/d3d11/mlgshaders/textured-ps.hlsl b/gfx/layers/d3d11/mlgshaders/textured-ps.hlsl deleted file mode 100644 index e00f6cbc4488..000000000000 --- a/gfx/layers/d3d11/mlgshaders/textured-ps.hlsl +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common.hlsl" -#include "common-ps.hlsl" -#include "textured-common.hlsl" - -Texture2D simpleTex : register(ps, t0); - -float4 FixRGBOpacity(float4 color, float alpha) { - return float4(color.rgb * alpha, alpha); -} - -// Fast cases that don't require complex clipping. -float4 TexturedQuadRGBA(const VS_SAMPLEOUTPUT_CLIPPED aInput) : SV_Target -{ - return simpleTex.Sample(sSampler, aInput.vTexCoords) * sOpacity; -} -float4 TexturedQuadRGB(const VS_SAMPLEOUTPUT_CLIPPED aInput) : SV_Target -{ - return FixRGBOpacity(simpleTex.Sample(sSampler, aInput.vTexCoords), sOpacity); -} - -// PaintedLayer common case. -float4 TexturedVertexRGBA(const VS_SAMPLEOUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - return float4(0, 0, 0, 0); - } - - float alpha = ReadMask(aInput.vMaskCoords); - return simpleTex.Sample(sSampler, aInput.vTexCoords) * alpha; -} - -// ImageLayers. -float4 TexturedVertexRGB(const VS_SAMPLEOUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - return float4(0, 0, 0, 0); - } - - float alpha = ReadMask(aInput.vMaskCoords); - return FixRGBOpacity(simpleTex.Sample(sSampler, aInput.vTexCoords), alpha); -} diff --git a/gfx/layers/d3d11/mlgshaders/textured-vs.hlsl b/gfx/layers/d3d11/mlgshaders/textured-vs.hlsl deleted file mode 100644 index 89744acb1d35..000000000000 --- a/gfx/layers/d3d11/mlgshaders/textured-vs.hlsl +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-vs.hlsl" -#include "textured-common.hlsl" - -VS_SAMPLEOUTPUT TexturedQuadImpl(const VertexInfo aInfo, const float2 aTexCoord) -{ - VS_SAMPLEOUTPUT output; - output.vPosition = aInfo.worldPos; - output.vTexCoords = aTexCoord; - output.vLocalPos = aInfo.screenPos; - output.vClipRect = aInfo.clipRect; - output.vMaskCoords = aInfo.maskCoords; - return output; -} - -VS_SAMPLEOUTPUT_CLIPPED TexturedQuadVS(const VS_TEXTUREDINPUT aVertex) -{ - TexturedItem item = GetItem(aVertex.vIndex); - - float4 worldPos = ComputeClippedPosition( - aVertex.vPos, - aVertex.vRect, - aVertex.vLayerId, - aVertex.vDepth); - - VS_SAMPLEOUTPUT_CLIPPED output; - output.vPosition = worldPos; - output.vTexCoords = UnitQuadToRect(aVertex.vPos, item.texCoords); - return output; -} - -VS_SAMPLEOUTPUT TexturedVertexVS(const VS_TEXTUREDVERTEX aVertex) -{ - VertexInfo info = ComputePosition(aVertex.vLayerPos, aVertex.vLayerId, aVertex.vDepth); - - return TexturedQuadImpl(info, aVertex.vTexCoord); -} diff --git a/gfx/layers/d3d11/mlgshaders/ycbcr-ps.hlsl b/gfx/layers/d3d11/mlgshaders/ycbcr-ps.hlsl deleted file mode 100644 index acf76578cb09..000000000000 --- a/gfx/layers/d3d11/mlgshaders/ycbcr-ps.hlsl +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "common-ps.hlsl" -#include "textured-common.hlsl" - -Texture2D tY : register(ps, t0); -Texture2D tCb : register(ps, t1); -Texture2D tCr : register(ps, t2); - -cbuffer YCbCrBuffer : register(b1) { - row_major float3x3 YuvColorMatrix; -}; - -/* From Rec601: -[R] [1.1643835616438356, 0.0, 1.5960267857142858] [ Y - 16] -[G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708] x [Cb - 128] -[B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [Cr - 128] - -For [0,1] instead of [0,255], and to 5 places: -[R] [1.16438, 0.00000, 1.59603] [ Y - 0.06275] -[G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196] -[B] [1.16438, 2.01723, 0.00000] [Cr - 0.50196] - -From Rec709: -[R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [ Y - 16] -[G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444] x [Cb - 128] -[B] [1.1643835616438356, 2.1124017857142854, 0.0] [Cr - 128] - -For [0,1] instead of [0,255], and to 5 places: -[R] [1.16438, 0.00000, 1.79274] [ Y - 0.06275] -[G] = [1.16438, -0.21325, -0.53291] x [Cb - 0.50196] -[B] [1.16438, 2.11240, 0.00000] [Cr - 0.50196] -*/ -float4 CalculateYCbCrColor(float3 rgb) -{ - return float4( - mul(YuvColorMatrix, - float3( - rgb.r - 0.06275, - rgb.g - 0.50196, - rgb.b - 0.50196)), - 1.0); -} - -float4 CalculateIMC4Color(const float2 aTexCoords) -{ - float3 yuv = float3( - tY.Sample(sSampler, aTexCoords).r, - tCb.Sample(sSampler, aTexCoords).r, - tCr.Sample(sSampler, aTexCoords).r); - return CalculateYCbCrColor(yuv); -} - -float4 CalculateNV12Color(const float2 aTexCoords) -{ - float y = tY.Sample(sSampler, aTexCoords).r; - float2 cbcr = tCb.Sample(sSampler, aTexCoords).rg; - return CalculateYCbCrColor(float3(y, cbcr)); -} - -float4 TexturedQuadIMC4(const VS_SAMPLEOUTPUT_CLIPPED aInput) : SV_Target -{ - return CalculateIMC4Color(aInput.vTexCoords) * sOpacity; -} - -float4 TexturedQuadNV12(const VS_SAMPLEOUTPUT_CLIPPED aInput) : SV_Target -{ - return CalculateNV12Color(aInput.vTexCoords) * sOpacity; -} - -float4 TexturedVertexIMC4(const VS_SAMPLEOUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - return float4(0, 0, 0, 0); - } - - float alpha = ReadMask(aInput.vMaskCoords); - return CalculateIMC4Color(aInput.vTexCoords) * alpha; -} - -float4 TexturedVertexNV12(const VS_SAMPLEOUTPUT aInput) : SV_Target -{ - if (!RectContainsPoint(aInput.vClipRect, aInput.vPosition.xy)) { - return float4(0, 0, 0, 0); - } - - float alpha = ReadMask(aInput.vMaskCoords); - return CalculateNV12Color(aInput.vTexCoords) * alpha; -} diff --git a/gfx/layers/mlgpu/BufferCache.cpp b/gfx/layers/mlgpu/BufferCache.cpp deleted file mode 100644 index f81729d006c3..000000000000 --- a/gfx/layers/mlgpu/BufferCache.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "BufferCache.h" -#include "MLGDevice.h" -#include "mozilla/MathAlgorithms.h" - -namespace mozilla { -namespace layers { - -BufferCache::BufferCache(MLGDevice* aDevice) - : mDevice(aDevice) -{ -} - -BufferCache::~BufferCache() -{ -} - -RefPtr -BufferCache::GetOrCreateBuffer(size_t aBytes) -{ - // Try to take a buffer from the expired frame. If none exists, make a new one. - RefPtr buffer = mExpired.Take(aBytes); - if (!buffer) { - // Round up to the nearest size class, but not over 1024 bytes. - size_t roundedUp = std::max(std::min(RoundUpPow2(aBytes), size_t(1024)), aBytes); - buffer = mDevice->CreateBuffer(MLGBufferType::Constant, roundedUp, MLGUsage::Dynamic, nullptr); - if (!buffer) { - return nullptr; - } - } - - MOZ_ASSERT(buffer->GetSize() >= aBytes); - - // Assign this buffer to the current frame, so it becomes available again once - // this frame expires. - mCurrent.Put(buffer); - return buffer; -} - -void -BufferCache::EndFrame() -{ - BufferPool empty; - mExpired = Move(mPrevious); - mPrevious = Move(mCurrent); - mCurrent = Move(empty); -} - -RefPtr -BufferPool::Take(size_t aBytes) -{ - MOZ_ASSERT(aBytes >= 16); - - // We need to bump the request up to the nearest size class. For example, - // a request of 24 bytes must allocate from the 32 byte pool. - SizeClass sc = GetSizeClassFromHighBit(CeilingLog2(aBytes)); - if (sc == SizeClass::Huge) { - return TakeHugeBuffer(aBytes); - } - - if (mClasses[sc].IsEmpty()) { - return nullptr; - } - - RefPtr buffer = mClasses[sc].LastElement(); - mClasses[sc].RemoveElementAt(mClasses[sc].Length() - 1); - return buffer.forget(); -} - -void -BufferPool::Put(MLGBuffer* aBuffer) -{ - MOZ_ASSERT(aBuffer->GetSize() >= 16); - - // When returning buffers, we bump them into a lower size class. For example - // a 24 byte buffer cannot be re-used for a 32-byte allocation, so it goes - // into the 16-byte class. - SizeClass sc = GetSizeClassFromHighBit(FloorLog2(aBuffer->GetSize())); - if (sc == SizeClass::Huge) { - mHugeBuffers.push_back(aBuffer); - } else { - mClasses[sc].AppendElement(aBuffer); - } -} - -RefPtr -BufferPool::TakeHugeBuffer(size_t aBytes) -{ - static const size_t kMaxSearches = 3; - size_t numSearches = std::min(kMaxSearches, mHugeBuffers.size()); - - for (size_t i = 0; i < numSearches; i++) { - RefPtr buffer = mHugeBuffers.front(); - mHugeBuffers.pop_front(); - - // Don't pick buffers that are massively overallocated. - if (buffer->GetSize() >= aBytes && buffer->GetSize() <= aBytes * 2) { - return buffer.forget(); - } - - // Return the buffer to the list. - mHugeBuffers.push_back(buffer); - } - - return nullptr; -} - -/* static */ BufferPool::SizeClass -BufferPool::GetSizeClassFromHighBit(size_t aBit) -{ - // If the size is smaller than our smallest size class (which should - // never happen), or bigger than our largest size class, we dump it - // in the catch-all "huge" list. - static const size_t kBitForFirstClass = 4; - static const size_t kBitForLastClass = kBitForFirstClass + size_t(SizeClass::Huge); - if (aBit < kBitForFirstClass || aBit >= kBitForLastClass) { - return SizeClass::Huge; - } - return SizeClass(aBit - kBitForFirstClass); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/BufferCache.h b/gfx/layers/mlgpu/BufferCache.h deleted file mode 100644 index a79794dc852c..000000000000 --- a/gfx/layers/mlgpu/BufferCache.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_BufferCache_h -#define mozilla_gfx_layers_mlgpu_BufferCache_h - -#include "mozilla/EnumeratedArray.h" -#include "nsTArray.h" -#include - -namespace mozilla { -namespace layers { - -class MLGBuffer; -class MLGDevice; - -// This file defines a buffer caching mechanism for systems where constant -// buffer offset binding is not allowed. On those systems we must allocate -// new buffers each frame, and this cache allows us to re-use them. - -// Track buffers based on their size class, for small buffers. -class BufferPool -{ -public: - // Remove a buffer from the pool holding at least |aBytes|. - RefPtr Take(size_t aBytes); - - // Put a buffer into the pool holding at least |aBytes|. - void Put(MLGBuffer* aBuffer); - - BufferPool& operator =(BufferPool&& aOther) { - mClasses = Move(aOther.mClasses); - mHugeBuffers = Move(aOther.mHugeBuffers); - return *this; - } - -private: - // Try to see if we can quickly re-use any buffer that didn't fit into a - // pre-existing size class. - RefPtr TakeHugeBuffer(size_t aBytes); - - enum class SizeClass { - One, // 16+ bytes (one constant) - Two, // 32+ bytes (two constants) - Four, // 64+ bytes (four constants) - Eight, // 128+ bytes (eight constants) - Medium, // 256+ bytes (16 constants) - Large, // 512+ bytes (32 constants) - Huge // 1024+ bytes (64+ constants) - }; - static SizeClass GetSizeClassFromHighBit(size_t bit); - -private: - typedef nsTArray> BufferList; - EnumeratedArray mClasses; - std::deque> mHugeBuffers; -}; - -// Cache buffer pools based on how long ago they were last used. -class BufferCache -{ -public: - explicit BufferCache(MLGDevice* aDevice); - ~BufferCache(); - - // Get a buffer that has at least |aBytes|, or create a new one - // if none can be re-used. - RefPtr GetOrCreateBuffer(size_t aBytes); - - // Rotate buffers after a frame has been completed. - void EndFrame(); - -private: - // Not RefPtr since this would create a cycle. - MLGDevice* mDevice; - - // We keep three active buffer pools: - // The "expired" pool, which was used two frames ago. - // The "previous" pool, which is being used by the previous frame. - // The "current" pool, which is being used for the current frame. - // - // We always allocate from the expired pool into the current pool. - // After a frame is completed, the current is moved into the previous, - // and the previous is moved into the expired. The expired buffers - // are deleted if still alive. - // - // Since Layers does not allow us to composite more than one frame - // ahead, this system ensures the expired buffers are always free. - BufferPool mExpired; - BufferPool mPrevious; - BufferPool mCurrent; -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_BufferCache_h diff --git a/gfx/layers/mlgpu/CanvasLayerMLGPU.cpp b/gfx/layers/mlgpu/CanvasLayerMLGPU.cpp deleted file mode 100644 index 2aba8ac1efe5..000000000000 --- a/gfx/layers/mlgpu/CanvasLayerMLGPU.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CanvasLayerMLGPU.h" -#include "composite/CompositableHost.h" // for CompositableHost -#include "gfx2DGlue.h" // for ToFilter -#include "gfxEnv.h" // for gfxEnv, etc -#include "mozilla/gfx/Matrix.h" // for Matrix4x4 -#include "mozilla/gfx/Point.h" // for Point -#include "mozilla/gfx/Rect.h" // for Rect -#include "mozilla/layers/Compositor.h" // for Compositor -#include "mozilla/layers/Effects.h" // for EffectChain -#include "mozilla/layers/ImageHost.h" -#include "mozilla/mozalloc.h" // for operator delete -#include "nsAString.h" -#include "mozilla/RefPtr.h" // for nsRefPtr -#include "MaskOperation.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc -#include "nsString.h" // for nsAutoCString - -namespace mozilla { -namespace layers { - -using namespace mozilla::gfx; - -CanvasLayerMLGPU::CanvasLayerMLGPU(LayerManagerMLGPU* aManager) - : CanvasLayer(aManager, nullptr) - , TexturedLayerMLGPU(aManager) -{ -} - -CanvasLayerMLGPU::~CanvasLayerMLGPU() -{ - CleanupResources(); -} - -Layer* -CanvasLayerMLGPU::GetLayer() -{ - return this; -} - -gfx::SamplingFilter -CanvasLayerMLGPU::GetSamplingFilter() -{ - gfx::SamplingFilter filter = mSamplingFilter; -#ifdef ANDROID - // Bug 691354 - // Using the LINEAR filter we get unexplained artifacts. - // Use NEAREST when no scaling is required. - Matrix matrix; - bool is2D = GetEffectiveTransform().Is2D(&matrix); - if (is2D && !ThebesMatrix(matrix).HasNonTranslationOrFlip()) { - filter = SamplingFilter::POINT; - } -#endif - return filter; -} - -void -CanvasLayerMLGPU::PrintInfo(std::stringstream& aStream, const char* aPrefix) -{ - CanvasLayer::PrintInfo(aStream, aPrefix); - aStream << "\n"; - if (mHost && mHost->IsAttached()) { - nsAutoCString pfx(aPrefix); - pfx += " "; - mHost->PrintInfo(aStream, pfx.get()); - } -} - -void -CanvasLayerMLGPU::CleanupResources() -{ - if (mHost) { - mHost->Detach(this); - } - mTexture = nullptr; - mBigImageTexture = nullptr; - mHost = nullptr; -} - -void -CanvasLayerMLGPU::Disconnect() -{ - CleanupResources(); -} - -void -CanvasLayerMLGPU::ClearCachedResources() -{ - CleanupResources(); -} - -void -CanvasLayerMLGPU::SetRegionToRender(LayerIntRegion&& aRegion) -{ - aRegion.AndWith(LayerIntRect::FromUnknownRect(mPictureRect)); - LayerMLGPU::SetRegionToRender(Move(aRegion)); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/CanvasLayerMLGPU.h b/gfx/layers/mlgpu/CanvasLayerMLGPU.h deleted file mode 100644 index 3b0a84dabd0c..000000000000 --- a/gfx/layers/mlgpu/CanvasLayerMLGPU.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef GFX_CanvasLayerMLGPU_H -#define GFX_CanvasLayerMLGPU_H - -#include "Layers.h" // for CanvasLayer, etc -#include "TexturedLayerMLGPU.h" -#include "mozilla/Attributes.h" // for override -#include "mozilla/RefPtr.h" // for RefPtr -#include "mozilla/layers/LayerManagerMLGPU.h" // for LayerComposite, etc -#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc -#include "nsDebug.h" // for NS_RUNTIMEABORT -#include "nsRect.h" // for mozilla::gfx::IntRect -#include "nscore.h" // for nsACString - -namespace mozilla { -namespace layers { - -class CompositableHost; -class ImageHost; - -class CanvasLayerMLGPU final : public CanvasLayer, - public TexturedLayerMLGPU -{ -public: - explicit CanvasLayerMLGPU(LayerManagerMLGPU* aManager); - -protected: - ~CanvasLayerMLGPU() override; - -public: - void Initialize(const Data& aData) override { - MOZ_CRASH("Incompatibe surface type"); - } - - Layer* GetLayer() override; - void Disconnect() override; - - HostLayer* AsHostLayer() override { return this; } - CanvasLayerMLGPU* AsCanvasLayerMLGPU() override { return this; } - gfx::SamplingFilter GetSamplingFilter() override; - void ClearCachedResources() override; - void SetRegionToRender(LayerIntRegion&& aRegion) override; - - MOZ_LAYER_DECL_NAME("CanvasLayerMLGPU", TYPE_CANVAS) - -protected: - void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; - void CleanupResources(); -}; - -} // namespace layers -} // namespace mozilla - -#endif /* GFX_CanvasLayerMLGPU_H */ diff --git a/gfx/layers/mlgpu/ContainerLayerMLGPU.cpp b/gfx/layers/mlgpu/ContainerLayerMLGPU.cpp deleted file mode 100644 index 2a243a06c819..000000000000 --- a/gfx/layers/mlgpu/ContainerLayerMLGPU.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ContainerLayerMLGPU.h" -#include "gfxPrefs.h" -#include "LayersLogging.h" -#include "MLGDevice.h" - -namespace mozilla { -namespace layers { - -ContainerLayerMLGPU::ContainerLayerMLGPU(LayerManagerMLGPU* aManager) - : ContainerLayer(aManager, nullptr) - , LayerMLGPU(aManager) -{ -} - -ContainerLayerMLGPU::~ContainerLayerMLGPU() -{ - while (mFirstChild) { - RemoveChild(mFirstChild); - } -} - -bool -ContainerLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder) -{ - if (!UseIntermediateSurface()) { - return true; - } - - mTargetOffset = GetIntermediateSurfaceRect().TopLeft().ToUnknownPoint(); - mTargetSize = GetIntermediateSurfaceRect().Size().ToUnknownSize(); - - if (mRenderTarget && mRenderTarget->GetSize() != mTargetSize) { - mRenderTarget = nullptr; - } - - IntRect viewport(IntPoint(0, 0), mTargetSize); - if (!mRenderTarget || !gfxPrefs::AdvancedLayersUseInvalidation()) { - // Fine-grained invalidation is disabled, invalidate everything. - mInvalidRect = viewport; - } else { - // Clamp the invalid rect to the viewport. - mInvalidRect = mInvalidRect.Intersect(viewport); - } - return true; -} - -RefPtr -ContainerLayerMLGPU::UpdateRenderTarget(MLGDevice* aDevice, MLGRenderTargetFlags aFlags) -{ - if (mRenderTarget) { - return mRenderTarget; - } - - mRenderTarget = aDevice->CreateRenderTarget(mTargetSize, aFlags); - if (!mRenderTarget) { - gfxWarning() << "Failed to create an intermediate render target for ContainerLayer"; - return nullptr; - } - - return mRenderTarget; -} - -void -ContainerLayerMLGPU::SetInvalidCompositeRect(const gfx::IntRect& aRect) -{ - // For simplicity we only track the bounds of the invalid area, since regions - // are expensive. We can adjust this in the future if needed. - IntRect bounds = aRect; - bounds.MoveBy(-GetTargetOffset()); - - // Note we add the bounds to the invalid rect from the last frame, since we - // only clear the area that we actually paint. - if (Maybe result = mInvalidRect.SafeUnion(bounds)) { - mInvalidRect = result.value(); - } else { - mInvalidRect = IntRect(IntPoint(0, 0), GetTargetSize()); - } -} - -void -ContainerLayerMLGPU::ClearCachedResources() -{ - mRenderTarget = nullptr; -} - -bool -ContainerLayerMLGPU::IsContentOpaque() -{ - if (GetMixBlendMode() != CompositionOp::OP_OVER) { - // We need to read from what's underneath us, so we consider our content to - // be not opaque. - return false; - } - return LayerMLGPU::IsContentOpaque(); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/ContainerLayerMLGPU.h b/gfx/layers/mlgpu/ContainerLayerMLGPU.h deleted file mode 100644 index ae6f37bda6a1..000000000000 --- a/gfx/layers/mlgpu/ContainerLayerMLGPU.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_ContainerLayerMLGPU_h -#define mozilla_gfx_layers_mlgpu_ContainerLayerMLGPU_h - -#include "LayerMLGPU.h" - -namespace mozilla { -namespace layers { - -class ContainerLayerMLGPU final : public ContainerLayer - , public LayerMLGPU -{ -public: - explicit ContainerLayerMLGPU(LayerManagerMLGPU* aManager); - ~ContainerLayerMLGPU() override; - - MOZ_LAYER_DECL_NAME("ContainerLayerMLGPU", TYPE_CONTAINER) - - HostLayer* AsHostLayer() override { return this; } - ContainerLayerMLGPU* AsContainerLayerMLGPU() override { return this; } - Layer* GetLayer() override { return this; } - - void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override { - DefaultComputeEffectiveTransforms(aTransformToSurface); - } - void SetInvalidCompositeRect(const gfx::IntRect &aRect) override; - void ClearCachedResources() override; - - RefPtr UpdateRenderTarget( - MLGDevice* aDevice, - MLGRenderTargetFlags aFlags); - - MLGRenderTarget* GetRenderTarget() const { - return mRenderTarget; - } - gfx::IntPoint GetTargetOffset() const { - return mTargetOffset; - } - gfx::IntSize GetTargetSize() const { - return mTargetSize; - } - const gfx::IntRect& GetInvalidRect() const { - return mInvalidRect; - } - void ClearInvalidRect() { - mInvalidRect.SetEmpty(); - } - bool IsContentOpaque() override; - -protected: - bool OnPrepareToRender(FrameBuilder* aBuilder) override; - -private: - RefPtr mRenderTarget; - - // We cache these since occlusion culling can change the visible region. - gfx::IntPoint mTargetOffset; - gfx::IntSize mTargetSize; - - // The region of the container that needs to be recomposited if visible. We - // store this as a rectangle instead of an nsIntRegion for efficiency. - gfx::IntRect mInvalidRect; -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_ContainerLayerMLGPU_h diff --git a/gfx/layers/mlgpu/FrameBuilder.cpp b/gfx/layers/mlgpu/FrameBuilder.cpp deleted file mode 100644 index 292a69c5f2c9..000000000000 --- a/gfx/layers/mlgpu/FrameBuilder.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "FrameBuilder.h" -#include "ContainerLayerMLGPU.h" -#include "GeckoProfiler.h" // for profiler_* -#include "LayerMLGPU.h" -#include "LayerManagerMLGPU.h" -#include "MaskOperation.h" -#include "RenderPassMLGPU.h" -#include "RenderViewMLGPU.h" -#include "mozilla/layers/LayersHelpers.h" - -namespace mozilla { -namespace layers { - -using namespace mlg; - -FrameBuilder::FrameBuilder(LayerManagerMLGPU* aManager, MLGSwapChain* aSwapChain) - : mManager(aManager), - mDevice(aManager->GetDevice()), - mSwapChain(aSwapChain) -{ - // test_bug1124898.html has a root ColorLayer, so we don't assume the root is - // a container. - mRoot = mManager->GetRoot()->AsHostLayer()->AsLayerMLGPU(); -} - -FrameBuilder::~FrameBuilder() -{ -} - -bool -FrameBuilder::Build() -{ - PROFILER_LABEL("FrameBuilder", "Build", js::ProfileEntry::Category::GRAPHICS); - - // AcquireBackBuffer can fail, so we check the result here. - RefPtr target = mSwapChain->AcquireBackBuffer(); - if (!target) { - return false; - } - - // This updates the frame sequence number, so layers can quickly check if - // they've already been prepared. - LayerMLGPU::BeginFrame(); - - // Note: we don't clip draw calls to the invalid region per se, but instead - // the region bounds. Clipping all draw calls would incur a significant - // CPU cost on large layer trees, and would greatly complicate how draw - // rects are added in RenderPassMLGPU, since we would need to break - // each call into additional items based on the intersection with the - // invalid region. - // - // Instead we scissor to the invalid region bounds. As a result, all items - // affecting the invalid bounds are redrawn, even if not all are in the - // precise region. - const nsIntRegion& region = mSwapChain->GetBackBufferInvalidRegion(); - - mWidgetRenderView = new RenderViewMLGPU(this, target, region); - - // Traverse the layer tree and assign each layer to tiles. - { - Maybe geometry; - RenderTargetIntRect clip(0, 0, target->GetSize().width, target->GetSize().height); - - AssignLayer(mRoot->GetLayer(), mWidgetRenderView, clip, Move(geometry)); - } - - // Build the default mask buffer. - { - MaskInformation defaultMaskInfo(1.0f, false); - if (!mDevice->GetSharedPSBuffer()->Allocate(&mDefaultMaskInfo, defaultMaskInfo)) { - return false; - } - } - - // Build render passes and buffer information for each pass. - mWidgetRenderView->FinishBuilding(); - mWidgetRenderView->Prepare(); - - // Prepare masks that need to be combined. - for (const auto& pair : mCombinedTextureMasks) { - pair.second->PrepareForRendering(); - } - - FinishCurrentLayerBuffer(); - FinishCurrentMaskRectBuffer(); - return true; -} - -void -FrameBuilder::Render() -{ - PROFILER_LABEL("FrameBuilder", "Render", js::ProfileEntry::Category::GRAPHICS); - - // Render combined masks into single mask textures. - for (const auto& pair : mCombinedTextureMasks) { - pair.second->Render(); - } - - // Render to all targets, front-to-back. - mWidgetRenderView->Render(); -} - -void -FrameBuilder::AssignLayer(Layer* aLayer, - RenderViewMLGPU* aView, - const RenderTargetIntRect& aClipRect, - Maybe&& aGeometry) -{ - LayerMLGPU* layer = aLayer->AsHostLayer()->AsLayerMLGPU(); - - if (ContainerLayer* container = aLayer->AsContainerLayer()) { - // This returns false if we don't need to (or can't) process the layer any - // further. This always returns false for non-leaf ContainerLayers. - if (!ProcessContainerLayer(container, aView, aClipRect, aGeometry)) { - return; - } - } else { - // Set the precomputed clip and any textures/resources that are needed. - if (!layer->PrepareToRender(this, aClipRect)) { - return; - } - } - - // If we are dealing with a nested 3D context, we might need to transform - // the geometry back to the coordinate space of the current layer. - if (aGeometry) { - TransformLayerGeometry(aLayer, aGeometry); - } - - // Finally, assign the layer to a rendering batch in the current render - // target. - layer->AssignToView(this, aView, Move(aGeometry)); -} - -bool -FrameBuilder::ProcessContainerLayer(ContainerLayer* aContainer, - RenderViewMLGPU* aView, - const RenderTargetIntRect& aClipRect, - Maybe& aGeometry) -{ - LayerMLGPU* layer = aContainer->AsHostLayer()->AsLayerMLGPU(); - - // We don't want to traverse containers twice, so we only traverse them if - // they haven't been prepared yet. - bool isFirstVisit = !layer->IsPrepared(); - if (isFirstVisit && !layer->PrepareToRender(this, aClipRect)) { - return false; - } - - // If the container is not part of the invalid region, we don't draw it - // or traverse it. Note that we do not pass the geometry here. Otherwise - // we could decide the particular split is not visible, and because of the - // check above, never bother traversing the container again. - IntRect boundingBox = layer->GetClippedBoundingBox(aView, Nothing()); - const IntRect& invalidRect = aView->GetInvalidRect(); - if (boundingBox.IsEmpty() || !invalidRect.Intersects(boundingBox)) { - return false; - } - - if (!aContainer->UseIntermediateSurface()) { - // In case the layer previously required an intermediate surface, we - // clear any intermediate render targets here. - layer->ClearCachedResources(); - - // This is a pass-through container, so we just process children and - // instruct AssignLayer to early-return. - ProcessChildList(aContainer, aView, aClipRect, aGeometry); - return false; - } - - // If this is the first visit of the container this frame, and the - // container has an unpainted area, we traverse the container. Note that - // RefLayers do not have intermediate surfaces so this is guaranteed - // to be a full-fledged ContainerLayerMLGPU. - ContainerLayerMLGPU* viewContainer = layer->AsContainerLayerMLGPU(); - if (isFirstVisit && !viewContainer->GetInvalidRect().IsEmpty()) { - // The RenderView constructor automatically attaches itself to the parent. - RefPtr view = new RenderViewMLGPU(this, viewContainer, aView); - ProcessChildList(aContainer, view, aClipRect, Nothing()); - view->FinishBuilding(); - } - return true; -} - -void -FrameBuilder::ProcessChildList(ContainerLayer* aContainer, - RenderViewMLGPU* aView, - const RenderTargetIntRect& aParentClipRect, - const Maybe& aParentGeometry) -{ - nsTArray polygons = - aContainer->SortChildrenBy3DZOrder(ContainerLayer::SortMode::WITH_GEOMETRY); - - // Visit layers in front-to-back order. - for (auto iter = polygons.rbegin(); iter != polygons.rend(); iter++) { - LayerPolygon& entry = *iter; - Layer* child = entry.layer; - if (child->IsBackfaceHidden() || !child->IsVisible()) { - continue; - } - - RenderTargetIntRect clip = child->CalculateScissorRect(aParentClipRect); - if (clip.IsEmpty()) { - continue; - } - - Maybe geometry; - if (aParentGeometry && entry.geometry) { - // Both parent and child are split. - geometry = Some(aParentGeometry->ClipPolygon(*entry.geometry)); - } else if (aParentGeometry) { - geometry = aParentGeometry; - } else if (entry.geometry) { - geometry = Move(entry.geometry); - } - - AssignLayer(child, aView, clip, Move(geometry)); - } -} - -bool -FrameBuilder::AddLayerToConstantBuffer(ItemInfo& aItem) -{ - LayerMLGPU* layer = aItem.layer; - - // If this layer could appear multiple times, cache it. - if (aItem.geometry) { - if (mLayerBufferMap.Get(layer, &aItem.layerIndex)) { - return true; - } - } - - LayerConstants* info = AllocateLayerInfo(aItem); - if (!info) { - return false; - } - - // Note we do not use GetEffectiveTransformForBuffer, since we calculate - // the correct scaling when we build texture coordinates. - Layer* baseLayer = layer->GetLayer(); - const Matrix4x4& transform = baseLayer->GetEffectiveTransform(); - - memcpy(&info->transform, &transform._11, 64); - info->clipRect = Rect(layer->GetComputedClipRect().ToUnknownRect()); - info->maskIndex = 0; - if (MaskOperation* op = layer->GetMask()) { - // Note: we use 0 as an invalid index, and so indices are offset by 1. - Rect rect = op->ComputeMaskRect(baseLayer); - AddMaskRect(rect, &info->maskIndex); - } - - if (aItem.geometry) { - mLayerBufferMap.Put(layer, aItem.layerIndex); - } - return true; -} - -MaskOperation* -FrameBuilder::AddMaskOperation(LayerMLGPU* aLayer) -{ - Layer* layer = aLayer->GetLayer(); - MOZ_ASSERT(layer->HasMaskLayers()); - - // Multiple masks are combined into a single mask. - if ((layer->GetMaskLayer() && layer->GetAncestorMaskLayerCount()) || - layer->GetAncestorMaskLayerCount() > 1) - { - // Since each mask can be moved independently of the other, we must create - // a separate combined mask for every new positioning we encounter. - MaskTextureList textures; - if (Layer* maskLayer = layer->GetMaskLayer()) { - AppendToMaskTextureList(textures, maskLayer); - } - for (size_t i = 0; i < layer->GetAncestorMaskLayerCount(); i++) { - AppendToMaskTextureList(textures, layer->GetAncestorMaskLayerAt(i)); - } - - auto iter = mCombinedTextureMasks.find(textures); - if (iter != mCombinedTextureMasks.end()) { - return iter->second; - } - - RefPtr op = new MaskCombineOperation(this); - op->Init(textures); - - mCombinedTextureMasks[textures] = op; - return op; - } - - Layer* maskLayer = layer->GetMaskLayer() - ? layer->GetMaskLayer() - : layer->GetAncestorMaskLayerAt(0); - RefPtr texture = GetMaskLayerTexture(maskLayer); - if (!texture) { - return nullptr; - } - - RefPtr op; - mSingleTextureMasks.Get(texture, getter_AddRefs(op)); - if (op) { - return op; - } - - RefPtr wrapped = mDevice->CreateTexture(texture); - - op = new MaskOperation(this, wrapped); - mSingleTextureMasks.Put(texture, op); - return op; -} - -void -FrameBuilder::RetainTemporaryLayer(LayerMLGPU* aLayer) -{ - // This should only be used with temporary layers. Temporary layers do not - // have parents. - MOZ_ASSERT(!aLayer->GetLayer()->GetParent()); - mTemporaryLayers.push_back(aLayer->GetLayer()); -} - -LayerConstants* -FrameBuilder::AllocateLayerInfo(ItemInfo& aItem) -{ - if (((mCurrentLayerBuffer.Length() + 1) * sizeof(LayerConstants)) > - mDevice->GetMaxConstantBufferBindSize()) - { - FinishCurrentLayerBuffer(); - mLayerBufferMap.Clear(); - mCurrentLayerBuffer.ClearAndRetainStorage(); - } - - LayerConstants* info = mCurrentLayerBuffer.AppendElement(mozilla::fallible); - if (!info) { - return nullptr; - } - - aItem.layerIndex = mCurrentLayerBuffer.Length() - 1; - return info; -} - -void -FrameBuilder::FinishCurrentLayerBuffer() -{ - if (mCurrentLayerBuffer.IsEmpty()) { - return; - } - - // Note: we append the buffer even if we couldn't allocate one, since - // that keeps the indices sane. - ConstantBufferSection section; - mDevice->GetSharedVSBuffer()->Allocate( - §ion, - mCurrentLayerBuffer.Elements(), - mCurrentLayerBuffer.Length()); - mLayerBuffers.AppendElement(section); -} - -size_t -FrameBuilder::CurrentLayerBufferIndex() const -{ - // The mask rect buffer list doesn't contain the buffer currently being - // built, so we don't subtract 1 here. - return mLayerBuffers.Length(); -} - -ConstantBufferSection -FrameBuilder::GetLayerBufferByIndex(size_t aIndex) const -{ - if (aIndex >= mLayerBuffers.Length()) { - return ConstantBufferSection(); - } - return mLayerBuffers[aIndex]; -} - -bool -FrameBuilder::AddMaskRect(const gfx::Rect& aRect, uint32_t* aOutIndex) -{ - if (((mCurrentMaskRectList.Length() + 1) * sizeof(gfx::Rect)) > - mDevice->GetMaxConstantBufferBindSize()) - { - FinishCurrentMaskRectBuffer(); - mCurrentMaskRectList.ClearAndRetainStorage(); - } - - mCurrentMaskRectList.AppendElement(aRect); - - // Mask indices start at 1 so the shader can use 0 as a no-mask indicator. - *aOutIndex = mCurrentMaskRectList.Length(); - return true; -} - -void -FrameBuilder::FinishCurrentMaskRectBuffer() -{ - if (mCurrentMaskRectList.IsEmpty()) { - return; - } - - // Note: we append the buffer even if we couldn't allocate one, since - // that keeps the indices sane. - ConstantBufferSection section; - mDevice->GetSharedVSBuffer()->Allocate( - §ion, - mCurrentMaskRectList.Elements(), - mCurrentMaskRectList.Length()); - mMaskRectBuffers.AppendElement(section); -} - -size_t -FrameBuilder::CurrentMaskRectBufferIndex() const -{ - // The mask rect buffer list doesn't contain the buffer currently being - // built, so we don't subtract 1 here. - return mMaskRectBuffers.Length(); -} - -ConstantBufferSection -FrameBuilder::GetMaskRectBufferByIndex(size_t aIndex) const -{ - if (aIndex >= mMaskRectBuffers.Length()) { - return ConstantBufferSection(); - } - return mMaskRectBuffers[aIndex]; -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/FrameBuilder.h b/gfx/layers/mlgpu/FrameBuilder.h deleted file mode 100644 index 80b839a2fb2b..000000000000 --- a/gfx/layers/mlgpu/FrameBuilder.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_FrameBuilder_h -#define mozilla_gfx_layers_mlgpu_FrameBuilder_h - -#include "mozilla/RefPtr.h" -#include "mozilla/gfx/Point.h" -#include "mozilla/gfx/Types.h" -#include "MaskOperation.h" -#include "nsDataHashtable.h" -#include "nsRefPtrHashtable.h" -#include "ShaderDefinitionsMLGPU.h" -#include "SharedBufferMLGPU.h" -#include "Units.h" -#include -#include - -namespace mozilla { -namespace layers { - -class ContainerLayer; -class ContainerLayerMLGPU; -class Layer; -class LayerMLGPU; -class LayerManagerMLGPU; -class MLGDevice; -class MLGRenderTarget; -class MLGSwapChain; -class RenderViewMLGPU; -struct ItemInfo; - -class FrameBuilder final -{ -public: - FrameBuilder(LayerManagerMLGPU* aManager, MLGSwapChain* aSwapChain); - ~FrameBuilder(); - - bool Build(); - void Render(); - - bool AddLayerToConstantBuffer(ItemInfo& aItem); - - LayerManagerMLGPU* GetManager() const { - return mManager; - } - MLGDevice* GetDevice() const { - return mDevice; - } - const ConstantBufferSection& GetDefaultMaskInfo() const { - return mDefaultMaskInfo; - } - - // Called during tile construction. Finds or adds a mask layer chain to the - // cache, that will be flattened as a dependency to rendering batches. - MaskOperation* AddMaskOperation(LayerMLGPU* aLayer); - - // Note: These should only be called during batch construction. - size_t CurrentLayerBufferIndex() const; - size_t CurrentMaskRectBufferIndex() const; - - // These are called during rendering, and may return null if a buffer - // couldn't be allocated. - ConstantBufferSection GetLayerBufferByIndex(size_t aIndex) const; - ConstantBufferSection GetMaskRectBufferByIndex(size_t aIndex) const; - - // Hold a layer alive until the frame ends. - void RetainTemporaryLayer(LayerMLGPU* aLayer); - -private: - void AssignLayer(Layer* aLayer, - RenderViewMLGPU* aView, - const RenderTargetIntRect& aClipRect, - Maybe&& aGeometry); - - void ProcessChildList(ContainerLayer* aContainer, - RenderViewMLGPU* aView, - const RenderTargetIntRect& aParentClipRect, - const Maybe& aParentGeometry); - - mlg::LayerConstants* AllocateLayerInfo(ItemInfo& aItem); - bool AddMaskRect(const gfx::Rect& aRect, uint32_t* aOutIndex); - void FinishCurrentLayerBuffer(); - void FinishCurrentMaskRectBuffer(); - - // Returns true to continue, false to stop - false does not indicate - // failure. - bool ProcessContainerLayer(ContainerLayer* aLayer, - RenderViewMLGPU* aView, - const RenderTargetIntRect& aClipRect, - Maybe& aGeometry); - -private: - RefPtr mManager; - RefPtr mDevice; - RefPtr mSwapChain; - RefPtr mWidgetRenderView; - LayerMLGPU* mRoot; - - // Each time we consume a layer in a tile, we make sure a constant buffer - // exists that contains information about the layer. The mapping is valid - // for the most recent buffer, and once the buffer fills, we begin a new - // one and clear the map. - nsTArray mLayerBuffers; - nsTArray mCurrentLayerBuffer; - nsDataHashtable, uint32_t> mLayerBufferMap; - - // We keep mask rects in a separate buffer since they're rare. - nsTArray mMaskRectBuffers; - nsTArray mCurrentMaskRectList; - - // For values that *can* change every render pass, but almost certainly do - // not, we pre-fill and cache some buffers. - ConstantBufferSection mDefaultMaskInfo; - - // Cache for MaskOperations. - nsRefPtrHashtable, MaskOperation> mSingleTextureMasks; - std::map> mCombinedTextureMasks; - - // This list of temporary layers is wiped out when the frame is completed. - std::vector> mTemporaryLayers; -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_FrameBuilder_h diff --git a/gfx/layers/mlgpu/ImageLayerMLGPU.cpp b/gfx/layers/mlgpu/ImageLayerMLGPU.cpp deleted file mode 100644 index 88aff09ad5fb..000000000000 --- a/gfx/layers/mlgpu/ImageLayerMLGPU.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ImageLayerMLGPU.h" -#include "LayerManagerMLGPU.h" - -namespace mozilla { - -using namespace gfx; - -namespace layers { - -ImageLayerMLGPU::ImageLayerMLGPU(LayerManagerMLGPU* aManager) - : ImageLayer(aManager, static_cast(this)) - , TexturedLayerMLGPU(aManager) -{ -} - -ImageLayerMLGPU::~ImageLayerMLGPU() -{ - CleanupResources(); -} - -void -ImageLayerMLGPU::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) -{ - Matrix4x4 local = GetLocalTransform(); - - // Snap image edges to pixel boundaries. - gfxRect sourceRect(0, 0, 0, 0); - if (mHost && mHost->IsAttached()) { - IntSize size = mHost->GetImageSize(); - sourceRect.SizeTo(size.width, size.height); - } - - // Snap our local transform first, and snap the inherited transform as well. - // This makes our snapping equivalent to what would happen if our content - // was drawn into a PaintedLayer (gfxContext would snap using the local - // transform, then we'd snap again when compositing the PaintedLayer). - mEffectiveTransform = - SnapTransform(local, sourceRect, nullptr) * - SnapTransformTranslation(aTransformToSurface, nullptr); - mEffectiveTransformForBuffer = mEffectiveTransform; - - if (mScaleMode == ScaleMode::STRETCH && - mScaleToSize.width != 0.0 && - mScaleToSize.height != 0.0) - { - Size scale( - sourceRect.width / mScaleToSize.width, - sourceRect.height / mScaleToSize.height); - mScale = Some(scale); - } - - ComputeEffectiveTransformForMaskLayers(aTransformToSurface); -} - -gfx::SamplingFilter -ImageLayerMLGPU::GetSamplingFilter() -{ - return ImageLayer::GetSamplingFilter(); -} - -bool -ImageLayerMLGPU::IsContentOpaque() -{ - if (mPictureRect.width == 0 || mPictureRect.height == 0) { - return false; - } - if (mScaleMode == ScaleMode::STRETCH) { - return gfx::IsOpaque(mHost->CurrentTextureHost()->GetFormat()); - } - return false; -} - -void -ImageLayerMLGPU::SetRegionToRender(LayerIntRegion&& aRegion) -{ - // See bug 1264142. - if (mScaleMode == ScaleMode::STRETCH) { - aRegion.AndWith(LayerIntRect(0, 0, mScaleToSize.width, mScaleToSize.height)); - } - LayerMLGPU::SetRegionToRender(Move(aRegion)); -} - -void -ImageLayerMLGPU::CleanupResources() -{ - if (mHost) { - mHost->CleanupResources(); - mHost->Detach(this); - } - mTexture = nullptr; - mBigImageTexture = nullptr; - mHost = nullptr; -} - -void -ImageLayerMLGPU::PrintInfo(std::stringstream& aStream, const char* aPrefix) -{ - ImageLayer::PrintInfo(aStream, aPrefix); - if (mHost && mHost->IsAttached()) { - aStream << "\n"; - nsAutoCString pfx(aPrefix); - pfx += " "; - mHost->PrintInfo(aStream, pfx.get()); - } -} - -void -ImageLayerMLGPU::Disconnect() -{ - CleanupResources(); -} - -void -ImageLayerMLGPU::ClearCachedResources() -{ - CleanupResources(); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/ImageLayerMLGPU.h b/gfx/layers/mlgpu/ImageLayerMLGPU.h deleted file mode 100644 index 39ac9183940f..000000000000 --- a/gfx/layers/mlgpu/ImageLayerMLGPU.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MOZILLA_GFX_IMAGELAYERMLGPU_H -#define MOZILLA_GFX_IMAGELAYERMLGPU_H - -#include "LayerManagerMLGPU.h" -#include "TexturedLayerMLGPU.h" -#include "ImageLayers.h" -#include "mozilla/layers/ImageHost.h" - -namespace mozilla { -namespace layers { - -class ImageLayerMLGPU final : public ImageLayer - , public TexturedLayerMLGPU -{ -public: - explicit ImageLayerMLGPU(LayerManagerMLGPU* aManager); - - - Layer* GetLayer() override { return this; } - HostLayer* AsHostLayer() override { return this; } - ImageLayerMLGPU* AsImageLayerMLGPU() override { return this; } - - void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override; - void SetRegionToRender(LayerIntRegion&& aRegion) override; - gfx::SamplingFilter GetSamplingFilter() override; - void ClearCachedResources() override; - bool IsContentOpaque() override; - void Disconnect() override; - - Maybe GetPictureScale() const override { - return mScale; - } - - MOZ_LAYER_DECL_NAME("ImageLayerMLGPU", TYPE_IMAGE) - -protected: - ~ImageLayerMLGPU() override; - - void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; - void CleanupResources(); - -private: - Maybe mScale; -}; - -} // namespace layers -} // namespace mozilla - -#endif diff --git a/gfx/layers/mlgpu/LayerMLGPU.cpp b/gfx/layers/mlgpu/LayerMLGPU.cpp deleted file mode 100644 index 24ba3d8d192b..000000000000 --- a/gfx/layers/mlgpu/LayerMLGPU.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "LayerManagerMLGPU.h" -#include "RenderPassMLGPU.h" -#include "RenderViewMLGPU.h" -#include "FrameBuilder.h" -#include "mozilla/layers/ImageHost.h" - -namespace mozilla { -namespace layers { - -using namespace gfx; - -uint64_t LayerMLGPU::sFrameKey = 0; - -LayerMLGPU::LayerMLGPU(LayerManagerMLGPU* aManager) - : HostLayer(aManager), - mFrameKey(0), - mPrepared(false) -{ -} - -/* static */ void -LayerMLGPU::BeginFrame() -{ - sFrameKey++; -} - -LayerManagerMLGPU* -LayerMLGPU::GetManager() -{ - return static_cast(mCompositorManager); -} - -bool -LayerMLGPU::PrepareToRender(FrameBuilder* aBuilder, const RenderTargetIntRect& aClipRect) -{ - if (mFrameKey == sFrameKey) { - return mPrepared; - } - mFrameKey = sFrameKey; - mPrepared = false; - - Layer* layer = GetLayer(); - - // Only container layers may have mixed blend modes. - MOZ_ASSERT_IF(layer->GetMixBlendMode() != CompositionOp::OP_OVER, - layer->GetType() == Layer::TYPE_CONTAINER); - - mComputedClipRect = aClipRect; - - if (layer->HasMaskLayers()) { - mMask = aBuilder->AddMaskOperation(this); - } else { - mMask = nullptr; - } - - if (!OnPrepareToRender(aBuilder)) { - return false; - } - - mComputedOpacity = layer->GetEffectiveOpacity(); - mPrepared = true; - return true; -} - -void -LayerMLGPU::AssignToView(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - Maybe&& aGeometry) -{ - AddBoundsToView(aBuilder, aView, Move(aGeometry)); -} - -void -LayerMLGPU::AddBoundsToView(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - Maybe&& aGeometry) -{ - IntRect bounds = GetClippedBoundingBox(aView, aGeometry); - aView->AddItem(this, bounds, Move(aGeometry)); -} - -IntRect -LayerMLGPU::GetClippedBoundingBox(RenderViewMLGPU* aView, - const Maybe& aGeometry) -{ - MOZ_ASSERT(IsPrepared()); - - Layer* layer = GetLayer(); - const Matrix4x4& transform = layer->GetEffectiveTransform(); - - Rect rect = aGeometry - ? aGeometry->BoundingBox() - : Rect(layer->GetLocalVisibleRegion().GetBounds().ToUnknownRect()); - rect = transform.TransformBounds(rect); - rect.MoveBy(-aView->GetTargetOffset()); - rect = rect.Intersect(Rect(mComputedClipRect.ToUnknownRect())); - - IntRect bounds; - rect.RoundOut(); - rect.ToIntRect(&bounds); - return bounds; -} - -void -LayerMLGPU::MarkPrepared() -{ - mFrameKey = sFrameKey; - mPrepared = true; -} - -bool -LayerMLGPU::IsContentOpaque() -{ - return GetLayer()->IsOpaque(); -} - -void -LayerMLGPU::SetRegionToRender(LayerIntRegion&& aRegion) -{ - SetShadowVisibleRegion(Move(aRegion)); -} - -RefLayerMLGPU::RefLayerMLGPU(LayerManagerMLGPU* aManager) - : RefLayer(aManager, static_cast(this)) - , LayerMLGPU(aManager) -{ -} - -RefLayerMLGPU::~RefLayerMLGPU() -{ -} - -ColorLayerMLGPU::ColorLayerMLGPU(LayerManagerMLGPU* aManager) - : ColorLayer(aManager, static_cast(this)) - , LayerMLGPU(aManager) -{ -} - -ColorLayerMLGPU::~ColorLayerMLGPU() -{ -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/LayerMLGPU.h b/gfx/layers/mlgpu/LayerMLGPU.h deleted file mode 100644 index 528a1b293678..000000000000 --- a/gfx/layers/mlgpu/LayerMLGPU.h +++ /dev/null @@ -1,166 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_LayerMLGPU_h -#define mozilla_gfx_layers_mlgpu_LayerMLGPU_h - -#include "Layers.h" -#include "mozilla/layers/LayerManagerComposite.h" - -namespace mozilla { -namespace layers { - -class CanvasLayerMLGPU; -class ColorLayerMLGPU; -class ContainerLayerMLGPU; -class FrameBuilder; -class ImageHost; -class ImageLayerMLGPU; -class LayerManagerMLGPU; -class MaskOperation; -class MLGRenderTarget; -class PaintedLayerMLGPU; -class RefLayerMLGPU; -class RenderViewMLGPU; -class TexturedLayerMLGPU; -class TextureSource; - -class LayerMLGPU : public HostLayer -{ -public: - LayerMLGPU* AsLayerMLGPU() override { return this; } - virtual PaintedLayerMLGPU* AsPaintedLayerMLGPU() { return nullptr; } - virtual ImageLayerMLGPU* AsImageLayerMLGPU() { return nullptr; } - virtual CanvasLayerMLGPU* AsCanvasLayerMLGPU() { return nullptr; } - virtual ContainerLayerMLGPU* AsContainerLayerMLGPU() { return nullptr; } - virtual RefLayerMLGPU* AsRefLayerMLGPU() { return nullptr; } - virtual ColorLayerMLGPU* AsColorLayerMLGPU() { return nullptr; } - virtual TexturedLayerMLGPU* AsTexturedLayerMLGPU() { return nullptr; } - - static void BeginFrame(); - - // Ask the layer to acquire any resources or per-frame information needed - // to render. If this returns false, the layer will be skipped entirely. - bool PrepareToRender(FrameBuilder* aBuilder, const RenderTargetIntRect& aClipRect); - - Layer::LayerType GetType() { - return GetLayer()->GetType(); - } - const RenderTargetIntRect& GetComputedClipRect() const { - return mComputedClipRect; - } - MaskOperation* GetMask() const { - return mMask; - } - float GetComputedOpacity() const { - return mComputedOpacity; - } - - // Return the bounding box of this layer in render target space, clipped to - // the computed clip rect, and rounded out to an integer rect. - gfx::IntRect GetClippedBoundingBox(RenderViewMLGPU* aView, - const Maybe& aGeometry); - - // If this layer has already been prepared for the current frame, return - // true. This should only be used to guard against double-processing - // container layers after 3d-sorting. - bool IsPrepared() const { - return mFrameKey == sFrameKey && mPrepared; - } - - // Return true if the content in this layer is opaque (not factoring in - // blend modes or opacity), false otherwise. - virtual bool IsContentOpaque(); - - // This is a wrapper around SetShadowVisibleRegion. Some layers have visible - // regions that extend beyond what is actually drawn. When performing CPU- - // based occlusion culling we must clamp the visible region to the actual - // area. - virtual void SetRegionToRender(LayerIntRegion&& aRegion); - - virtual void AssignToView(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - Maybe&& aGeometry); - - // Callback for when PrepareToRender has finished successfully. If this - // returns false, PrepareToRender will return false. - virtual bool OnPrepareToRender(FrameBuilder* aBuilder) { - return true; - } - - virtual void ClearCachedResources() {} - virtual CompositableHost* GetCompositableHost() override { - return nullptr; - } - -protected: - LayerMLGPU(LayerManagerMLGPU* aManager); - LayerManagerMLGPU* GetManager(); - - void AddBoundsToView(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - Maybe&& aGeometry); - - void MarkPrepared(); - -private: - // This is a monotonic counter used to check whether a layer appears twice - // when 3d sorting. - static uint64_t sFrameKey; - -protected: - // These are set during PrepareToRender. - RenderTargetIntRect mComputedClipRect; - RefPtr mMask; - uint64_t mFrameKey; - float mComputedOpacity; - bool mPrepared; -}; - -class RefLayerMLGPU final : public RefLayer - , public LayerMLGPU -{ -public: - explicit RefLayerMLGPU(LayerManagerMLGPU* aManager); - ~RefLayerMLGPU() override; - - // Layer - HostLayer* AsHostLayer() override { return this; } - RefLayerMLGPU* AsRefLayerMLGPU() override { return this; } - Layer* GetLayer() override { return this; } - - // ContainerLayer - void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override - { - DefaultComputeEffectiveTransforms(aTransformToSurface); - } - - MOZ_LAYER_DECL_NAME("RefLayerMLGPU", TYPE_REF) -}; - -class ColorLayerMLGPU final : public ColorLayer - , public LayerMLGPU -{ -public: - explicit ColorLayerMLGPU(LayerManagerMLGPU* aManager); - ~ColorLayerMLGPU() override; - - // LayerMLGPU - bool IsContentOpaque() override { - return mColor.a >= 1.0f; - } - - // Layer - HostLayer* AsHostLayer() override { return this; } - ColorLayerMLGPU* AsColorLayerMLGPU() override { return this; } - Layer* GetLayer() override { return this; } - - MOZ_LAYER_DECL_NAME("ColorLayerMLGPU", TYPE_COLOR) -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_LayerMLGPU_h diff --git a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp deleted file mode 100644 index 15e555c047c4..000000000000 --- a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp +++ /dev/null @@ -1,579 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "LayerManagerMLGPU.h" -#include "LayerTreeInvalidation.h" -#include "PaintedLayerMLGPU.h" -#include "ImageLayerMLGPU.h" -#include "CanvasLayerMLGPU.h" -#include "GeckoProfiler.h" // for profiler_* -#include "MLGDevice.h" -#include "RenderPassMLGPU.h" -#include "RenderViewMLGPU.h" -#include "ShaderDefinitionsMLGPU.h" -#include "SharedBufferMLGPU.h" -#include "UnitTransforms.h" -#include "TextureSourceProviderMLGPU.h" -#include "TreeTraversal.h" -#include "FrameBuilder.h" -#include "LayersLogging.h" -#include "UtilityMLGPU.h" -#include "mozilla/layers/Diagnostics.h" -#include "mozilla/layers/TextRenderer.h" - -#ifdef XP_WIN -#include "mozilla/widget/WinCompositorWidget.h" -#include "mozilla/gfx/DeviceManagerDx.h" -#endif - -using namespace std; - -namespace mozilla { -namespace layers { - -using namespace gfx; - -static const int kDebugOverlayX = 2; -static const int kDebugOverlayY = 5; -static const int kDebugOverlayMaxWidth = 600; -static const int kDebugOverlayMaxHeight = 96; - -LayerManagerMLGPU::LayerManagerMLGPU(widget::CompositorWidget* aWidget) - : mWidget(aWidget), - mDrawDiagnostics(false), - mUsingInvalidation(false), - mCurrentFrame(nullptr) -{ - if (!aWidget) { - return; - } - - if (!mDevice) { - gfxWarning() << "Could not acquire an MLGDevice!"; - return; - } - - mSwapChain = mDevice->CreateSwapChainForWidget(aWidget); - if (!mSwapChain) { - gfxWarning() << "Could not acquire an MLGSwapChain!"; - return; - } - - mDiagnostics = MakeUnique(); - mTextRenderer = new TextRenderer(); -} - -LayerManagerMLGPU::~LayerManagerMLGPU() -{ - if (mTextureSourceProvider) { - mTextureSourceProvider->Destroy(); - } -} - -bool -LayerManagerMLGPU::Initialize() -{ - if (!mDevice || !mSwapChain) { - return false; - } - - mTextureSourceProvider = new TextureSourceProviderMLGPU(this, mDevice); - return true; -} - -void -LayerManagerMLGPU::Destroy() -{ - if (IsDestroyed()) { - return; - } - - LayerManager::Destroy(); - - if (mDevice && mDevice->IsValid()) { - mDevice->Flush(); - } - if (mSwapChain) { - mSwapChain->Destroy(); - mSwapChain = nullptr; - } - if (mTextureSourceProvider) { - mTextureSourceProvider->Destroy(); - mTextureSourceProvider = nullptr; - } - mWidget = nullptr; - mDevice = nullptr; -} - -void -LayerManagerMLGPU::ForcePresent() -{ - if (!mDevice->IsValid()) { - return; - } - - IntSize windowSize = mWidget->GetClientSize().ToUnknownSize(); - if (mSwapChain->GetSize() != windowSize) { - return; - } - - mSwapChain->ForcePresent(); -} - -already_AddRefed -LayerManagerMLGPU::CreateContainerLayer() -{ - return MakeAndAddRef(this); -} - -already_AddRefed -LayerManagerMLGPU::CreateColorLayer() -{ - return MakeAndAddRef(this); -} - -already_AddRefed -LayerManagerMLGPU::CreateRefLayer() -{ - return MakeAndAddRef(this); -} - -already_AddRefed -LayerManagerMLGPU::CreatePaintedLayer() -{ - return MakeAndAddRef(this); -} - -already_AddRefed -LayerManagerMLGPU::CreateImageLayer() -{ - return MakeAndAddRef(this); -} - -already_AddRefed -LayerManagerMLGPU::CreateBorderLayer() -{ - MOZ_ASSERT_UNREACHABLE("Not yet implemented"); - return nullptr; -} - -already_AddRefed -LayerManagerMLGPU::CreateTextLayer() -{ - MOZ_ASSERT_UNREACHABLE("Not yet implemented"); - return nullptr; -} - -already_AddRefed -LayerManagerMLGPU::CreateCanvasLayer() -{ - return MakeAndAddRef(this); -} - -TextureFactoryIdentifier -LayerManagerMLGPU::GetTextureFactoryIdentifier() -{ - TextureFactoryIdentifier ident; - if (mDevice) { - ident = mDevice->GetTextureFactoryIdentifier(); - } - ident.mSupportsBackdropCopyForComponentAlpha = SupportsBackdropCopyForComponentAlpha(); - return ident; -} - -LayersBackend -LayerManagerMLGPU::GetBackendType() -{ - return mDevice ? mDevice->GetLayersBackend() : LayersBackend::LAYERS_NONE; -} - -bool -LayerManagerMLGPU::BeginTransaction() -{ - MOZ_ASSERT(!mTarget); - return true; -} - -void -LayerManagerMLGPU::BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget, - const gfx::IntRect& aRect) -{ - MOZ_ASSERT(!mTarget); - - mTarget = aTarget; - mTargetRect = aRect; - return; -} - -// Helper class for making sure textures are unlocked. -class MOZ_STACK_CLASS AutoUnlockAllTextures -{ -public: - explicit AutoUnlockAllTextures(MLGDevice* aDevice) - : mDevice(aDevice) - {} - ~AutoUnlockAllTextures() { - mDevice->UnlockAllTextures(); - } - -private: - RefPtr mDevice; -}; - -void -LayerManagerMLGPU::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFlags aFlags) -{ - PROFILER_LABEL("LayerManager", "EndTransaction", - js::ProfileEntry::Category::GRAPHICS); - - SetCompositionTime(aTimeStamp); - - TextureSourceProvider::AutoReadUnlockTextures unlock(mTextureSourceProvider); - - if (!mRoot || (aFlags & END_NO_IMMEDIATE_REDRAW) || !mWidget) { - return; - } - - mCompositionStartTime = TimeStamp::Now(); - - IntSize windowSize = mWidget->GetClientSize().ToUnknownSize(); - if (windowSize.IsEmpty()) { - return; - } - - // Resize the window if needed. - if (mSwapChain->GetSize() != windowSize) { - // Note: all references to the backbuffer must be cleared. - mDevice->SetRenderTarget(nullptr); - if (!mSwapChain->ResizeBuffers(windowSize)) { - gfxCriticalNote << "Could not resize the swapchain (" << - hexa(windowSize.width) << "," << hexa(windowSize.height) << ")"; - return; - } - } - - mDrawDiagnostics = gfxPrefs::LayersDrawFPS(); - mUsingInvalidation = gfxPrefs::AdvancedLayersUseInvalidation(); - - // Compute transforms - and the changed area, if enabled. - mRoot->ComputeEffectiveTransforms(Matrix4x4()); - ComputeInvalidRegion(); - - // Build and execute draw commands, and present. - if (PreRender()) { - Composite(); - PostRender(); - } - - // Finish composition. - mLastCompositionEndTime = TimeStamp::Now(); -} - -void -LayerManagerMLGPU::Composite() -{ - PROFILER_LABEL("LayerManagerMLGPU", "Composite", - js::ProfileEntry::Category::GRAPHICS); - - // Don't composite if we're minimized/hidden, or if there is nothing to draw. - if (mWidget->IsHidden()) { - return; - } - - // Make sure the diagnostic area gets invalidated. We do this now, rather than - // earlier, so we don't accidentally cause extra composites. - Maybe diagnosticRect; - if (mDrawDiagnostics) { - diagnosticRect = Some(IntRect( - kDebugOverlayX, kDebugOverlayY, - kDebugOverlayMaxWidth, kDebugOverlayMaxHeight)); - } - - AL_LOG("Computed invalid region: %s\n", Stringify(mInvalidRegion).c_str()); - - // Now that we have the final invalid region, give it to the swap chain which - // will tell us if we still need to render. - if (!mSwapChain->ApplyNewInvalidRegion(Move(mInvalidRegion), diagnosticRect)) { - return; - } - - AutoUnlockAllTextures autoUnlock(mDevice); - - mDevice->BeginFrame(); - - RenderLayers(); - - if (mDrawDiagnostics) { - DrawDebugOverlay(); - } - - if (mTarget) { - mSwapChain->CopyBackbuffer(mTarget, mTargetRect); - mTarget = nullptr; - mTargetRect = IntRect(); - } - mSwapChain->Present(); - - // We call this here to mimic the behavior in LayerManagerComposite, as to - // not change what Talos measures. That is, we do not record an empty frame - // as a frame, since we short-circuit at the top of this function. - RecordFrame(); - - mDevice->EndFrame(); -} - -void -LayerManagerMLGPU::RenderLayers() -{ - PROFILER_LABEL("LayerManagerMLGPU", "RenderLayers", - js::ProfileEntry::Category::GRAPHICS); - - // Traverse the layer tree and assign each layer to a render target. - FrameBuilder builder(this, mSwapChain); - mCurrentFrame = &builder; - - if (!builder.Build()) { - return; - } - - if (mDrawDiagnostics) { - mDiagnostics->RecordPrepareTime((TimeStamp::Now() - mCompositionStartTime).ToMilliseconds()); - } - - // Make sure we acquire/release the sync object. - if (!mDevice->Synchronize()) { - // Catastrophic failure - probably a device reset. - return; - } - - TimeStamp start = TimeStamp::Now(); - - // Upload shared buffers. - mDevice->FinishSharedBufferUse(); - - // Prepare the pipeline. - if (mDrawDiagnostics) { - IntSize size = mSwapChain->GetBackBufferInvalidRegion().GetBounds().Size(); - uint32_t numPixels = size.width * size.height; - mDevice->StartDiagnostics(numPixels); - } - - // Execute all render passes. - builder.Render(); - mCurrentFrame = nullptr; - - if (mDrawDiagnostics) { - mDiagnostics->RecordCompositeTime((TimeStamp::Now() - start).ToMilliseconds()); - mDevice->EndDiagnostics(); - } -} - -void -LayerManagerMLGPU::DrawDebugOverlay() -{ - IntSize windowSize = mSwapChain->GetSize(); - - GPUStats stats; - mDevice->GetDiagnostics(&stats); - stats.mScreenPixels = windowSize.width * windowSize.height; - - std::string text = mDiagnostics->GetFrameOverlayString(stats); - RefPtr texture = mTextRenderer->RenderText( - mTextureSourceProvider, - text, - 30, - 600, - TextRenderer::FontType::FixedWidth); - if (!texture) { - return; - } - - if (mUsingInvalidation && - (texture->GetSize().width > kDebugOverlayMaxWidth || - texture->GetSize().height > kDebugOverlayMaxHeight)) - { - gfxCriticalNote << "Diagnostic overlay exceeds invalidation area: %s" << Stringify(texture->GetSize()).c_str(); - } - - struct DebugRect { - Rect bounds; - Rect texCoords; - }; - - if (!mDiagnosticVertices) { - DebugRect rect; - rect.bounds = Rect(Point(kDebugOverlayX, kDebugOverlayY), Size(texture->GetSize())); - rect.texCoords = Rect(0.0, 0.0, 1.0, 1.0); - - VertexStagingBuffer instances; - if (!instances.AppendItem(rect)) { - return; - } - - mDiagnosticVertices = mDevice->CreateBuffer( - MLGBufferType::Vertex, - instances.NumItems() * instances.SizeOfItem(), - MLGUsage::Immutable, - instances.GetBufferStart()); - if (!mDiagnosticVertices) { - return; - } - } - - // Note: we rely on the world transform being correctly left bound by the - // outermost render view. - mDevice->SetScissorRect(Nothing()); - mDevice->SetDepthTestMode(MLGDepthTestMode::Disabled); - mDevice->SetTopology(MLGPrimitiveTopology::UnitQuad); - mDevice->SetVertexShader(VertexShaderID::DiagnosticText); - mDevice->SetVertexBuffer(1, mDiagnosticVertices, sizeof(DebugRect)); - mDevice->SetPixelShader(PixelShaderID::DiagnosticText); - mDevice->SetBlendState(MLGBlendState::Over); - mDevice->SetPSTexture(0, texture); - mDevice->SetSamplerMode(0, SamplerMode::Point); - mDevice->DrawInstanced(4, 1, 0, 0); -} - -void -LayerManagerMLGPU::ComputeInvalidRegion() -{ - // If invalidation is disabled, throw away cloned properties and redraw the - // whole target area. - if (!mUsingInvalidation) { - mInvalidRegion = mTarget ? mTargetRect : mRenderBounds; - mNextFrameInvalidRegion.SetEmpty(); - return; - } - - nsIntRegion changed; - if (mClonedLayerTreeProperties) { - changed = mClonedLayerTreeProperties->ComputeDifferences(mRoot, nullptr); - } else { - changed = mRenderBounds; - } - - // We compute the change region, but if we're painting to a target, we save - // it for the next frame instead. - if (mTarget) { - mInvalidRegion = mTargetRect; - mNextFrameInvalidRegion.OrWith(changed); - } else { - mInvalidRegion = Move(mNextFrameInvalidRegion); - mInvalidRegion.OrWith(changed); - } - - // Free the old cloned property tree, then clone a new one. Note that we do - // this before compositing since our CPU-based occlusion culling will update - // the visible region to contain non-occluded draw rects. If a layer will not - // be drawn, it will have no visible region. LTI might save this, and if the - // layer is removed next frame, LTI will invalidate the wrong area. - // - // Instead, we always invalidate based on the full shadow tree. - // - // Note that the old compositor performs CPU-based occlusion culling *before* - // invalidation. This maintains consistency, but we have more accurate draw - // regions. - mClonedLayerTreeProperties = nullptr; - mClonedLayerTreeProperties = LayerProperties::CloneFrom(mRoot); -} - -void -LayerManagerMLGPU::AddInvalidRegion(const nsIntRegion& aRegion) -{ - mNextFrameInvalidRegion.OrWith(aRegion); -} - -TextureSourceProvider* -LayerManagerMLGPU::GetTextureSourceProvider() const -{ - return mTextureSourceProvider; -} - -bool -LayerManagerMLGPU::IsCompositingToScreen() const -{ - return !mTarget; -} - -bool -LayerManagerMLGPU::AreComponentAlphaLayersEnabled() -{ - return LayerManager::AreComponentAlphaLayersEnabled(); -} - -bool -LayerManagerMLGPU::BlendingRequiresIntermediateSurface() -{ - return true; -} - -bool -LayerManagerMLGPU::SupportsBackdropCopyForComponentAlpha() -{ - return false; -} - -void -LayerManagerMLGPU::EndTransaction(DrawPaintedLayerCallback aCallback, - void* aCallbackData, - EndTransactionFlags aFlags) -{ - MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)"); -} - -void -LayerManagerMLGPU::ClearCachedResources(Layer* aSubtree) -{ - Layer* root = aSubtree ? aSubtree : mRoot.get(); - if (!root) { - return; - } - - ForEachNode(root, [](Layer* aLayer) { - LayerMLGPU* layer = aLayer->AsHostLayer()->AsLayerMLGPU(); - if (!layer) { - return; - } - layer->ClearCachedResources(); - }); -} - -void -LayerManagerMLGPU::NotifyShadowTreeTransaction() -{ - if (gfxPrefs::LayersDrawFPS()) { - mDiagnostics->AddTxnFrame(); - } -} - -void -LayerManagerMLGPU::UpdateRenderBounds(const gfx::IntRect& aRect) -{ - mRenderBounds = aRect; -} - -bool -LayerManagerMLGPU::PreRender() -{ - PROFILER_LABEL("LayerManagerMLGPU", "PreRender", - js::ProfileEntry::Category::GRAPHICS); - - widget::WidgetRenderingContext context; - if (!mWidget->PreRender(&context)) { - return false; - } - mWidgetContext = Some(context); - return true; -} - -void -LayerManagerMLGPU::PostRender() -{ - mWidget->PostRender(mWidgetContext.ptr()); - mWidgetContext = Nothing(); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/LayerManagerMLGPU.h b/gfx/layers/mlgpu/LayerManagerMLGPU.h deleted file mode 100644 index 88c48587dad8..000000000000 --- a/gfx/layers/mlgpu/LayerManagerMLGPU.h +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MOZILLA_GFX_LAYERMANAGERMLGPU_H -#define MOZILLA_GFX_LAYERMANAGERMLGPU_H - -#include "Layers.h" -#include "mozilla/layers/LayerManagerComposite.h" -#include "LayerMLGPU.h" - -namespace mozilla { -namespace layers { - -class FrameBuilder; -class LayerManagerMLGPU; -class RenderPassMLGPU; -class SharedBufferMLGPU; -class RenderViewMLGPU; -class TextRenderer; -class TextureSourceProviderMLGPU; -class MLGBuffer; -class MLGDevice; -class MLGSwapChain; -class MLGTileBuffer; -struct LayerProperties; - -class LayerManagerMLGPU final : public HostLayerManager -{ -public: - explicit LayerManagerMLGPU(widget::CompositorWidget* aWidget); - ~LayerManagerMLGPU(); - - bool Initialize(); - void Destroy() override; - - // LayerManager methods - bool BeginTransaction() override; - void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget, const gfx::IntRect& aRect) override; - void SetRoot(Layer* aLayer) override { mRoot = aLayer; } - already_AddRefed CreatePaintedLayer() override; - already_AddRefed CreateContainerLayer() override; - already_AddRefed CreateImageLayer() override; - already_AddRefed CreateColorLayer() override; - already_AddRefed CreateTextLayer() override; - already_AddRefed CreateCanvasLayer() override; - already_AddRefed CreateRefLayer() override; - already_AddRefed CreateBorderLayer() override; - - bool AreComponentAlphaLayersEnabled() override; - bool BlendingRequiresIntermediateSurface() override; - bool SupportsBackdropCopyForComponentAlpha() override; - - // HostLayerManager methods - void ForcePresent() override; - TextureFactoryIdentifier GetTextureFactoryIdentifier() override; - LayersBackend GetBackendType() override; - void AddInvalidRegion(const nsIntRegion& aRegion) override; - void ClearApproximatelyVisibleRegions(uint64_t aLayersId, - const Maybe& aPresShellId) override {} - void UpdateApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid, - const CSSIntRegion& aRegion) override {} - void EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFlags aFlags) override; - void EndTransaction(DrawPaintedLayerCallback aCallback, - void* aCallbackData, - EndTransactionFlags aFlags) override; - Compositor* GetCompositor() const override { - return nullptr; - } - bool IsCompositingToScreen() const override; - TextureSourceProvider* GetTextureSourceProvider() const override; - void ClearCachedResources(Layer* aSubtree = nullptr) override; - void NotifyShadowTreeTransaction() override; - void UpdateRenderBounds(const gfx::IntRect& aRect) override; - - LayerManagerMLGPU* AsLayerManagerMLGPU() override { - return this; - } - const char* Name() const override { - return ""; - } - - // This should only be called while a FrameBuilder is live. - FrameBuilder* GetCurrentFrame() const { - MOZ_ASSERT(mCurrentFrame); - return mCurrentFrame; - } - MLGDevice* GetDevice() { - return mDevice; - } - - TimeStamp GetLastCompositionEndTime() const { - return mLastCompositionEndTime; - } - -private: - void Composite(); - void ComputeInvalidRegion(); - void RenderLayers(); - void DrawDebugOverlay(); - bool PreRender(); - void PostRender(); - -private: - RefPtr mDevice; - RefPtr mSwapChain; - RefPtr mTextureSourceProvider; - RefPtr mTextRenderer; - widget::CompositorWidget* mWidget; - - UniquePtr mClonedLayerTreeProperties; - nsIntRegion mNextFrameInvalidRegion; - gfx::IntRect mRenderBounds; - - // These are per-frame only. - bool mDrawDiagnostics; - bool mUsingInvalidation; - nsIntRegion mInvalidRegion; - Maybe mWidgetContext; - - IntSize mWindowSize; - TimeStamp mCompositionStartTime; - TimeStamp mLastCompositionEndTime; - - RefPtr mTarget; - gfx::IntRect mTargetRect; - FrameBuilder* mCurrentFrame; - - RefPtr mDiagnosticVertices; -}; - -} // namespace layers -} // namespace mozilla - -#endif diff --git a/gfx/layers/mlgpu/MLGDevice.cpp b/gfx/layers/mlgpu/MLGDevice.cpp deleted file mode 100644 index 9f7621727409..000000000000 --- a/gfx/layers/mlgpu/MLGDevice.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "MLGDevice.h" -#include "mozilla/layers/TextureHost.h" -#include "BufferCache.h" -#include "gfxPrefs.h" -#include "gfxUtils.h" -#include "ShaderDefinitionsMLGPU.h" -#include "SharedBufferMLGPU.h" - -namespace mozilla { -namespace layers { - -using namespace gfx; -using namespace mlg; - -MLGRenderTarget::MLGRenderTarget(MLGRenderTargetFlags aFlags) - : mFlags(aFlags), - mLastDepthStart(-1) -{ -} - -MLGSwapChain::MLGSwapChain() - : mIsDoubleBuffered(false) -{ -} - -bool -MLGSwapChain::ApplyNewInvalidRegion(nsIntRegion&& aRegion, const Maybe& aExtraRect) -{ - // We clamp the invalid region to the backbuffer size, otherwise the present - // can fail. - IntRect bounds(IntPoint(0, 0), GetSize()); - nsIntRegion invalid = Move(aRegion); - invalid.AndWith(bounds); - if (invalid.IsEmpty()) { - return false; - } - - if (aExtraRect) { - IntRect rect = aExtraRect.value().Intersect(bounds); - if (!rect.IsEmpty()) { - invalid.OrWith(rect); - } - } - - // This area is now invalid in the back and front buffers. Note that the front - // buffer is either totally valid or totally invalid, since either the last - // paint succeeded or was thrown out due to a buffer resize. Effectively, it - // will now contain the invalid region specific to this frame. - mBackBufferInvalid.OrWith(invalid); - AL_LOG("Backbuffer invalid region: %s\n", Stringify(mBackBufferInvalid).c_str()); - - if (mIsDoubleBuffered) { - mFrontBufferInvalid.OrWith(invalid); - AL_LOG("Frontbuffer invalid region: %s\n", Stringify(mFrontBufferInvalid).c_str()); - } - return true; -} - -MLGDevice::MLGDevice() - : mTopology(MLGPrimitiveTopology::Unknown), - mIsValid(false), - mCanUseClearView(false), - mCanUseConstantBufferOffsetBinding(false), - mMaxConstantBufferBindSize(0) -{ -} - -MLGDevice::~MLGDevice() -{ -} - -bool -MLGDevice::Initialize() -{ - if (!mMaxConstantBufferBindSize) { - return Fail("FEATURE_FAILURE_NO_MAX_CB_BIND_SIZE", "Failed to set a max constant buffer bind size"); - } - if (mMaxConstantBufferBindSize < mlg::kMaxConstantBufferSize) { - // StagingBuffer depends on this value being accurate, so for now we just - // double-check it here. - return Fail("FEATURE_FAILURE_MIN_MAX_CB_BIND_SIZE", "Minimum constant buffer bind size not met"); - } - - // We allow this to be pref'd off for testing. Switching it on enables - // Direct3D 11.0/Windows 7/OpenGL-style buffer code paths. - if (!gfxPrefs::AdvancedLayersEnableBufferSharing()) { - mCanUseConstantBufferOffsetBinding = false; - } - - // We allow this to be pref'd off for testing. Disabling it turns on - // ID3D11DeviceContext1::ClearView support, which is present on - // newer Windows 8+ drivers. - if (!gfxPrefs::AdvancedLayersEnableClearView()) { - mCanUseClearView = false; - } - - // When compositing normal sized layer trees, we typically have small vertex - // buffers. Empirically the vertex and pixel constant buffer sizes are generally - // under 1KB and the vertex constant buffer size is under 8KB. - static const size_t kDefaultVertexBufferSize = 4096; - static const size_t kDefaultVSConstantBufferSize = 512 * kConstantBufferElementSize; - static const size_t kDefaultPSConstantBufferSize = 256 * kConstantBufferElementSize; - - // Note: we create these after we've verified all the device-specific properties above. - mSharedVertexBuffer = MakeUnique(this, kDefaultVertexBufferSize); - mSharedVSBuffer = MakeUnique(this, kDefaultVSConstantBufferSize); - mSharedPSBuffer = MakeUnique(this, kDefaultPSConstantBufferSize); - - if (!mSharedVertexBuffer->Init() || - !mSharedVSBuffer->Init() || - !mSharedPSBuffer->Init()) - { - return Fail("FEATURE_FAILURE_ALLOC_SHARED_BUFFER", "Failed to allocate a shared shader buffer"); - } - - if (gfxPrefs::AdvancedLayersEnableBufferCache()) { - mConstantBufferCache = MakeUnique(this); - } - - mInitialized = true; - mIsValid = true; - return true; -} - -void -MLGDevice::BeginFrame() -{ - mSharedVertexBuffer->Reset(); - mSharedPSBuffer->Reset(); - mSharedVSBuffer->Reset(); -} - -void -MLGDevice::EndFrame() -{ - if (mConstantBufferCache) { - mConstantBufferCache->EndFrame(); - } -} - -void -MLGDevice::FinishSharedBufferUse() -{ - mSharedVertexBuffer->PrepareForUsage(); - mSharedPSBuffer->PrepareForUsage(); - mSharedVSBuffer->PrepareForUsage(); -} - -void -MLGDevice::SetTopology(MLGPrimitiveTopology aTopology) -{ - if (mTopology == aTopology) { - return; - } - SetPrimitiveTopology(aTopology); - mTopology = aTopology; -} - -void -MLGDevice::SetVertexBuffer(uint32_t aSlot, VertexBufferSection* aSection) -{ - if (!aSection->IsValid()) { - return; - } - SetVertexBuffer(aSlot, aSection->GetBuffer(), aSection->Stride(), aSection->Offset()); -} - -void -MLGDevice::SetPSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection) -{ - if (!aSection->IsValid()) { - return; - } - - MLGBuffer* buffer = aSection->GetBuffer(); - - if (aSection->HasOffset()) { - uint32_t first = aSection->Offset(); - uint32_t numConstants = aSection->NumConstants(); - SetPSConstantBuffer(aSlot, buffer, first, numConstants); - } else { - SetPSConstantBuffer(aSlot, buffer); - } -} - -void -MLGDevice::SetVSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection) -{ - if (!aSection->IsValid()) { - return; - } - - MLGBuffer* buffer = aSection->GetBuffer(); - - if (aSection->HasOffset()) { - uint32_t first = aSection->Offset(); - uint32_t numConstants = aSection->NumConstants(); - SetVSConstantBuffer(aSlot, buffer, first, numConstants); - } else { - SetVSConstantBuffer(aSlot, buffer); - } -} - -void -MLGDevice::SetPSTexturesYUV(uint32_t aSlot, TextureSource* aTexture) -{ - // Note, we don't support tiled YCbCr textures. - const int Y = 0, Cb = 1, Cr = 2; - TextureSource* textures[3] = { - aTexture->GetSubSource(Y), - aTexture->GetSubSource(Cb), - aTexture->GetSubSource(Cr) - }; - MOZ_ASSERT(textures[0]); - MOZ_ASSERT(textures[1]); - MOZ_ASSERT(textures[2]); - - SetPSTextures(0, 3, textures); -} - -void -MLGDevice::SetPSTexture(uint32_t aSlot, TextureSource* aSource) -{ - SetPSTextures(aSlot, 1, &aSource); -} - -static inline SamplerMode -FilterToSamplerMode(gfx::SamplingFilter aFilter) -{ - switch (aFilter) { - case gfx::SamplingFilter::POINT: - return SamplerMode::Point; - case gfx::SamplingFilter::LINEAR: - case gfx::SamplingFilter::GOOD: - return SamplerMode::LinearClamp; - default: - MOZ_ASSERT_UNREACHABLE("Unknown sampler mode"); - return SamplerMode::LinearClamp; - } -} - -void -MLGDevice::SetSamplerMode(uint32_t aIndex, gfx::SamplingFilter aFilter) -{ - SetSamplerMode(aIndex, FilterToSamplerMode(aFilter)); -} - -bool -MLGDevice::Fail(const nsCString& aFailureId, const nsCString* aMessage) -{ - const char* message = aMessage - ? aMessage->get() - : "Failed initializing MLGDeviceD3D11"; - gfxWarning() << "Failure initializing MLGDeviceD3D11: " << message; - mFailureId = aFailureId; - mFailureMessage = message; - return false; -} - -void -MLGDevice::UnmapSharedBuffers() -{ - mSharedVertexBuffer->Reset(); - mSharedPSBuffer->Reset(); - mSharedVSBuffer->Reset(); -} - -RefPtr -MLGDevice::GetBufferForColorSpace(YUVColorSpace aColorSpace) -{ - if (mColorSpaceBuffers[aColorSpace]) { - return mColorSpaceBuffers[aColorSpace]; - } - - YCbCrShaderConstants buffer; - memcpy( - &buffer.yuvColorMatrix, - gfxUtils::YuvToRgbMatrix4x3RowMajor(aColorSpace), - sizeof(buffer.yuvColorMatrix)); - - RefPtr resource = CreateBuffer( - MLGBufferType::Constant, - sizeof(buffer), - MLGUsage::Immutable, - &buffer); - if (!resource) { - return nullptr; - } - - mColorSpaceBuffers[aColorSpace] = resource; - return resource; -} - -bool -MLGDevice::Synchronize() -{ - return true; -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/MLGDevice.h b/gfx/layers/mlgpu/MLGDevice.h deleted file mode 100644 index f32ba939f66d..000000000000 --- a/gfx/layers/mlgpu/MLGDevice.h +++ /dev/null @@ -1,476 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_MLGDevice_h -#define mozilla_gfx_layers_mlgpu_MLGDevice_h - -#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc -#include "mozilla/EnumeratedArray.h" -#include "mozilla/RefPtr.h" // for already_AddRefed, RefCounted -#include "mozilla/TypedEnumBits.h" -#include "mozilla/WidgetUtils.h" -#include "mozilla/gfx/Types.h" -#include "mozilla/layers/CompositorTypes.h" -#include "mozilla/layers/LayersTypes.h" -#include "ImageTypes.h" -#include "MLGDeviceTypes.h" -#include "nsISupportsImpl.h" -#include "nsString.h" -#include "nsPrintfCString.h" - -namespace mozilla { - -namespace widget { -class CompositorWidget; -} // namespace widget -namespace gfx { -class DrawTarget; -} // namespace gfx - -namespace layers { - -struct GPUStats; -class BufferCache; -class ConstantBufferSection; -class DataTextureSource; -class MLGBufferD3D11; -class MLGDeviceD3D11; -class MLGRenderTargetD3D11; -class MLGResourceD3D11; -class MLGTexture; -class MLGTextureD3D11; -class SharedVertexBuffer; -class SharedConstantBuffer; -class TextureSource; -class VertexBufferSection; - -class MLGRenderTarget -{ -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MLGRenderTarget) - - virtual gfx::IntSize GetSize() const = 0; - virtual MLGRenderTargetD3D11* AsD3D11() { return nullptr; } - - // Returns the underlying texture of the render target. - virtual MLGTexture* GetTexture() = 0; - - bool HasDepthBuffer() const { - return (mFlags & MLGRenderTargetFlags::ZBuffer) == MLGRenderTargetFlags::ZBuffer; - } - - int32_t GetLastDepthStart() const { - return mLastDepthStart; - } - void SetLastDepthStart(int32_t aDepthStart) { - mLastDepthStart = aDepthStart; - } - -protected: - explicit MLGRenderTarget(MLGRenderTargetFlags aFlags); - virtual ~MLGRenderTarget() {} - -protected: - MLGRenderTargetFlags mFlags; - - // When using a depth buffer, callers can track the range of depth values - // that were last used. - int32_t mLastDepthStart; -}; - -class MLGSwapChain -{ -protected: - virtual ~MLGSwapChain() {} - -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MLGSwapChain) - - virtual RefPtr AcquireBackBuffer() = 0; - virtual bool ResizeBuffers(const gfx::IntSize& aSize) = 0; - virtual gfx::IntSize GetSize() const = 0; - - // Present to the screen. - virtual void Present() = 0; - - // Force a present without waiting for the previous frame's present to complete. - virtual void ForcePresent() = 0; - - // Copy an area of the backbuffer to a draw target. - virtual void CopyBackbuffer(gfx::DrawTarget* aTarget, const gfx::IntRect& aBounds) = 0; - - // Free any internal resources. - virtual void Destroy() = 0; - - // Give the new invalid region to the swap chain in preparation for - // acquiring the backbuffer. If the new invalid region is empty, - // this returns false and no composite is required. - // - // The extra rect is used for the debug overlay, which is factored in - // separately to avoid causing unnecessary composites. - bool ApplyNewInvalidRegion(nsIntRegion&& aRegion, const Maybe& aExtraRect); - - const nsIntRegion& GetBackBufferInvalidRegion() const { - return mBackBufferInvalid; - } - -protected: - MLGSwapChain(); - -protected: - gfx::IntSize mLastPresentSize; - // The swap chain tracks the invalid region of its buffers. After presenting, - // the invalid region for the backbuffer is cleared. If using double - // buffering, it is set to the area of the non-presented buffer that was not - // painted this frame. The initial invalid region each frame comes from - // LayerManagerMLGPU, and is combined with the back buffer's invalid region - // before frame building begins. - nsIntRegion mBackBufferInvalid; - nsIntRegion mFrontBufferInvalid; - bool mIsDoubleBuffered; -}; - -class MLGResource -{ - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MLGResource) - -public: - enum class Type { - Buffer, - Texture - }; - - virtual Type GetType() const = 0; - virtual MLGResourceD3D11* AsResourceD3D11() { - return nullptr; - } - -protected: - virtual ~MLGResource() {} -}; - -// A buffer for use as a shader input. -class MLGBuffer : public MLGResource -{ -public: - Type GetType() const override { - return Type::Buffer; - } - virtual MLGBufferD3D11* AsD3D11() { - return nullptr; - } - virtual size_t GetSize() const = 0; - -protected: - ~MLGBuffer() override {} -}; - -// This is a lower-level resource than a TextureSource. It wraps -// a 2D texture. -class MLGTexture : public MLGResource -{ -public: - Type GetType() const override { - return Type::Texture; - } - virtual MLGTextureD3D11* AsD3D11() { - return nullptr; - } - const gfx::IntSize& GetSize() const { - return mSize; - } - -protected: - gfx::IntSize mSize; -}; - -enum class VertexShaderID -{ - TexturedQuad, - TexturedVertex, - ColoredQuad, - ColoredVertex, - BlendVertex, - Clear, - MaskCombiner, - DiagnosticText, - MaxShaders -}; - -enum class PixelShaderID -{ - ColoredQuad, - ColoredVertex, - TexturedQuadRGB, - TexturedQuadRGBA, - TexturedVertexRGB, - TexturedVertexRGBA, - TexturedQuadIMC4, - TexturedQuadNV12, - TexturedVertexIMC4, - TexturedVertexNV12, - ComponentAlphaQuad, - ComponentAlphaVertex, - BlendMultiply, - BlendScreen, - BlendOverlay, - BlendDarken, - BlendLighten, - BlendColorDodge, - BlendColorBurn, - BlendHardLight, - BlendSoftLight, - BlendDifference, - BlendExclusion, - BlendHue, - BlendSaturation, - BlendColor, - BlendLuminosity, - Clear, - MaskCombiner, - DiagnosticText, - MaxShaders -}; - -class MLGDevice -{ -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MLGDevice) - - MLGDevice(); - - virtual bool Initialize(); - - // If Initialize returns false, these may return more useful messages. - virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() const = 0; - virtual int32_t GetMaxTextureSize() const = 0; - virtual LayersBackend GetLayersBackend() const = 0; - - virtual RefPtr CreateSwapChainForWidget(widget::CompositorWidget* aWidget) = 0; - - // Markers for when we start and finish issuing "normal" (i.e., non- - // diagnostic) draw commands for the frame. - virtual void StartDiagnostics(uint32_t aInvalidPixels) = 0; - virtual void EndDiagnostics() = 0; - virtual void GetDiagnostics(GPUStats* aStats) = 0; - - // Layers interaction. - virtual RefPtr CreateDataTextureSource(TextureFlags aFlags) = 0; - - // Resource access - virtual bool Map(MLGResource* aResource, MLGMapType aType, MLGMappedResource* aMap) = 0; - virtual void Unmap(MLGResource* aResource) = 0; - virtual void UpdatePartialResource( - MLGResource* aResource, - const gfx::IntRect* aRect, - void* aData, - uint32_t aStride) = 0; - virtual void CopyTexture( - MLGTexture* aDest, - const gfx::IntPoint& aTarget, - MLGTexture* aSource, - const gfx::IntRect& aRect) = 0; - - // Begin a frame. This clears and resets all shared buffers. - virtual void BeginFrame(); - virtual void EndFrame(); - - // State setup commands. - virtual void SetRenderTarget(MLGRenderTarget* aRT) = 0; - virtual MLGRenderTarget* GetRenderTarget() = 0; - virtual void SetViewport(const gfx::IntRect& aRT) = 0; - virtual void SetScissorRect(const Maybe& aScissorRect) = 0; - virtual void SetVertexShader(VertexShaderID aVertexShader) = 0; - virtual void SetPixelShader(PixelShaderID aPixelShader) = 0; - virtual void SetSamplerMode(uint32_t aIndex, SamplerMode aSamplerMode) = 0; - virtual void SetBlendState(MLGBlendState aBlendState) = 0; - virtual void SetVertexBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aStride, uint32_t aOffset = 0) = 0; - virtual void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) = 0; - virtual void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) = 0; - virtual void SetPSTextures(uint32_t aSlot, uint32_t aNumTextures, TextureSource* const* aTextures) = 0; - virtual void SetPSTexture(uint32_t aSlot, MLGTexture* aTexture) = 0; - virtual void SetDepthTestMode(MLGDepthTestMode aMode) = 0; - - // If supported, bind constant buffers at a particular offset. These can only - // be used if CanUseConstantBufferOffsetBinding returns true. - virtual void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aFirstConstant, uint32_t aNumConstants) = 0; - virtual void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aFirstConstant, uint32_t aNumConstants) = 0; - - // Set the topology. No API call is made if the topology has not changed. - // The UnitQuad topology implicity binds a unit quad triangle strip as - // vertex buffer #0. - void SetTopology(MLGPrimitiveTopology aTopology); - - // Set textures that have special binding logic, and bind to multiple slots. - virtual void SetPSTexturesNV12(uint32_t aSlot, TextureSource* aTexture) = 0; - void SetPSTexturesYUV(uint32_t aSlot, TextureSource* aTexture); - - virtual RefPtr CreateBuffer( - MLGBufferType aType, - uint32_t aSize, - MLGUsage aUsage, - const void* aInitialData = nullptr) = 0; - - virtual RefPtr CreateTexture( - const gfx::IntSize& aSize, - gfx::SurfaceFormat aFormat, - MLGUsage aUsage, - MLGTextureFlags aFlags) = 0; - - // Unwrap the underlying GPU texture in the given TextureSource, and re-wrap - // it in an MLGTexture structure. - virtual RefPtr CreateTexture(TextureSource* aSource) = 0; - - virtual RefPtr CreateRenderTarget( - const gfx::IntSize& aSize, - MLGRenderTargetFlags aFlags = MLGRenderTargetFlags::Default) = 0; - - // Clear a render target to the given color, or clear a depth buffer. - virtual void Clear(MLGRenderTarget* aRT, const gfx::Color& aColor) = 0; - virtual void ClearDepthBuffer(MLGRenderTarget* aRT) = 0; - - // This is only available if CanUseClearView() returns true. - virtual void ClearView( - MLGRenderTarget* aRT, - const gfx::Color& aColor, - const gfx::IntRect* aRects, - size_t aNumRects) = 0; - - // Drawing Commands - virtual void Draw(uint32_t aVertexCount, uint32_t aOffset) = 0; - virtual void DrawInstanced(uint32_t aVertexCountPerInstance, uint32_t aInstanceCount, - uint32_t aVertexOffset, uint32_t aInstanceOffset) = 0; - virtual void Flush() = 0; - - // This unlocks any textures that were implicitly locked during drawing. - virtual void UnlockAllTextures() = 0; - - virtual MLGDeviceD3D11* AsD3D11() { return nullptr; } - - // Helpers. - void SetVertexBuffer(uint32_t aSlot, VertexBufferSection* aSection); - void SetPSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection); - void SetVSConstantBuffer(uint32_t aSlot, ConstantBufferSection* aSection); - void SetPSTexture(uint32_t aSlot, TextureSource* aSource); - void SetSamplerMode(uint32_t aIndex, gfx::SamplingFilter aFilter); - - // This creates or returns a previously created constant buffer, containing - // a YCbCrShaderConstants instance. - RefPtr GetBufferForColorSpace(YUVColorSpace aColorSpace); - - // A shared buffer that can be used to build VertexBufferSections. - SharedVertexBuffer* GetSharedVertexBuffer() { - return mSharedVertexBuffer.get(); - } - // A shared buffer that can be used to build ConstantBufferSections. Intended - // to be used with vertex shaders. - SharedConstantBuffer* GetSharedVSBuffer() { - return mSharedVSBuffer.get(); - } - // A shared buffer that can be used to build ConstantBufferSections. Intended - // to be used with pixel shaders. - SharedConstantBuffer* GetSharedPSBuffer() { - return mSharedPSBuffer.get(); - } - // A cache for constant buffers, used when offset-based binding is not supported. - BufferCache* GetConstantBufferCache() { - return mConstantBufferCache.get(); - } - - // Unmap and upload all shared buffers to the GPU. - void FinishSharedBufferUse(); - - // These are used to detect and report initialization failure. - virtual bool IsValid() const { - return mInitialized && mIsValid; - } - const nsCString& GetFailureId() const { - return mFailureId; - } - const nsCString& GetFailureMessage() const { - return mFailureMessage; - } - - // If supported, synchronize with the SyncObject given to clients. - virtual bool Synchronize(); - - // If this returns true, ClearView() can be called. - bool CanUseClearView() const { - return mCanUseClearView; - } - - // If this returns true, constant buffers can be bound at specific offsets for - // a given run of bytes. This is only supported on Windows 8+ for Direct3D 11. - bool CanUseConstantBufferOffsetBinding() const { - return mCanUseConstantBufferOffsetBinding; - } - - // Return the maximum number of elements that can be bound to a constant - // buffer. This is different than the maximum size of a buffer (there is - // no such limit on Direct3D 11.1). - size_t GetMaxConstantBufferBindSize() const { - return mMaxConstantBufferBindSize; - } - -protected: - virtual ~MLGDevice(); - - virtual void SetPrimitiveTopology(MLGPrimitiveTopology aTopology) = 0; - - // Used during initialization to record failure reasons. - bool Fail(const nsCString& aFailureId, const nsCString* aMessage); - - // Used during initialization to record failure reasons. Note: our - // MOZ_FORMAT_PRINTF macro does not work on this function, so we - // disable the warning. -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wformat-security" -#endif - template - bool Fail(const char* aFailureId) { - nsCString failureId(aFailureId); - return Fail(failureId, nullptr); - } - template - bool Fail(const char* aFailureId, - const char* aMessage, - const T&... args) - { - nsCString failureId(aFailureId); - nsPrintfCString message(aMessage, args...); - return Fail(failureId, &message); - } -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - - void UnmapSharedBuffers(); - -private: - MLGPrimitiveTopology mTopology; - UniquePtr mSharedVertexBuffer; - UniquePtr mSharedVSBuffer; - UniquePtr mSharedPSBuffer; - UniquePtr mConstantBufferCache; - - nsCString mFailureId; - nsCString mFailureMessage; - bool mInitialized; - - typedef EnumeratedArray> ColorSpaceArray; - ColorSpaceArray mColorSpaceBuffers; - -protected: - bool mIsValid; - bool mCanUseClearView; - bool mCanUseConstantBufferOffsetBinding; - size_t mMaxConstantBufferBindSize; -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_MLGDevice_h diff --git a/gfx/layers/mlgpu/MLGDeviceTypes.h b/gfx/layers/mlgpu/MLGDeviceTypes.h deleted file mode 100644 index 2ef3f5ac412d..000000000000 --- a/gfx/layers/mlgpu/MLGDeviceTypes.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_MLGDeviceTypes_h -#define mozilla_gfx_layers_mlgpu_MLGDeviceTypes_h - -#include "mozilla/TypedEnumBits.h" - -namespace mozilla { -namespace layers { - -enum class MLGUsage -{ - // GPU read-only, CPU write once on creation and read/write never. - Immutable, - - // GPU read-only, CPU write-only. Must be mapped with WRITE_DISCARD. - Dynamic, - - // GPU read/write-only, no CPU access. - Default, - - // GPU->CPU transfer, and read from the CPU. - Staging -}; - -enum class MLGDepthTestMode -{ - Disabled, - Write, - ReadOnly, - AlwaysWrite, - MaxModes -}; - -enum class MLGBufferType : uint32_t -{ - Vertex, - Constant -}; - -enum class SamplerMode -{ - // Linear filter, clamped to border. - LinearClamp = 0, - // Linear filter, clamped to transparent pixels. - LinearClampToZero, - // Point filter, clamped to border. - Point, - MaxModes -}; - -enum class MLGBlendState -{ - Copy = 0, - Over, - OverAndPremultiply, - Min, - ComponentAlpha, - MaxStates -}; - -enum class MLGPrimitiveTopology -{ - Unknown = 0, - TriangleStrip = 1, - TriangleList = 2, - UnitQuad = 3 -}; - -struct MLGMappedResource -{ - uint8_t* mData; - uint32_t mStride; -}; - -enum class MLGMapType -{ - READ = 0, - WRITE, - READ_WRITE, - WRITE_DISCARD -}; - -enum class MLGTextureFlags -{ - None, - ShaderResource, - RenderTarget -}; -MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(MLGTextureFlags); - -enum class MLGRenderTargetFlags : uint32_t -{ - Default = 0, - ZBuffer = (1 << 0) -}; -MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(MLGRenderTargetFlags); - -// NVIDIA drivers crash when we supply too many rects to ClearView - it -// seems to cause a stack overflow >= 20 rects. We cap to 12 for now. -static const size_t kMaxClearViewRects = 12; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_MLGDeviceTypes_h diff --git a/gfx/layers/mlgpu/MaskOperation.cpp b/gfx/layers/mlgpu/MaskOperation.cpp deleted file mode 100644 index 32b44c65e58c..000000000000 --- a/gfx/layers/mlgpu/MaskOperation.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "MaskOperation.h" -#include "FrameBuilder.h" -#include "LayerMLGPU.h" -#include "mozilla/layers/LayersHelpers.h" -#include "MLGDevice.h" -#include "TexturedLayerMLGPU.h" - -namespace mozilla { -namespace layers { - -using namespace gfx; - -MaskOperation::MaskOperation(FrameBuilder* aBuilder) -{ -} - -MaskOperation::MaskOperation(FrameBuilder* aBuilder, MLGTexture* aSource) - : mTexture(aSource) -{ -} - -MaskOperation::~MaskOperation() -{ -} - -static gfx::Rect -ComputeQuadForMaskLayer(Layer* aLayer, const IntSize& aSize) -{ - const Matrix4x4& transform = aLayer->GetEffectiveTransform(); - MOZ_ASSERT(transform.Is2D(), "Mask layers should not have 3d transforms"); - - Rect bounds(Point(0, 0), Size(aSize)); - return transform.As2D().TransformBounds(bounds); -} - -Rect -MaskOperation::ComputeMaskRect(Layer* aLayer) const -{ - Layer* maskLayer = aLayer->GetMaskLayer() - ? aLayer->GetMaskLayer() - : aLayer->GetAncestorMaskLayerAt(0); - MOZ_ASSERT((aLayer->GetAncestorMaskLayerCount() == 0 && aLayer->GetMaskLayer()) || - (aLayer->GetAncestorMaskLayerCount() == 1 && !aLayer->GetMaskLayer())); - - return ComputeQuadForMaskLayer(maskLayer, mTexture->GetSize()); -} - -// This is only needed for std::map. -bool -MaskTexture::operator <(const MaskTexture& aOther) const -{ - if (mRect.x != aOther.mRect.x) { - return mRect.x < aOther.mRect.x; - } - if (mRect.y != aOther.mRect.y) { - return mRect.y < aOther.mRect.y; - } - if (mRect.width != aOther.mRect.width) { - return mRect.width < aOther.mRect.width; - } - if (mRect.height != aOther.mRect.height) { - return mRect.height < aOther.mRect.height; - } - return mSource < aOther.mSource; -} - -RefPtr -GetMaskLayerTexture(Layer* aLayer) -{ - LayerMLGPU* layer = aLayer->AsHostLayer()->AsLayerMLGPU(); - TexturedLayerMLGPU* texLayer = layer->AsTexturedLayerMLGPU(); - if (!texLayer) { - MOZ_ASSERT_UNREACHABLE("Mask layers should be texture layers"); - return nullptr; - } - - RefPtr source = texLayer->BindAndGetTexture(); - if (!source) { - gfxWarning() << "Mask layer does not have a TextureSource"; - return nullptr; - } - return source.forget(); -} - -MaskCombineOperation::MaskCombineOperation(FrameBuilder* aBuilder) - : MaskOperation(aBuilder), - mBuilder(aBuilder) -{ -} - -MaskCombineOperation::~MaskCombineOperation() -{ -} - -void -MaskCombineOperation::Init(const MaskTextureList& aTextures) -{ - // All masks for a single layer exist in the same coordinate space. Find the - // area that covers all rects. - Rect area = aTextures[0].mRect; - for (size_t i = 1; i < aTextures.size(); i++) { - area = area.Intersect(aTextures[i].mRect); - } - - // Go through and decide which areas of the textures are relevant. - for (size_t i = 0; i < aTextures.size(); i++) { - Rect rect = aTextures[i].mRect.Intersect(area); - if (rect.IsEmpty()) { - continue; - } - - rect -= aTextures[i].mRect.TopLeft(); - mTextures.push_back(MaskTexture(rect, aTextures[i].mSource)); - } - - IntRect size; - Rect bounds = area; - bounds.RoundOut(); - bounds.ToIntRect(&size); - - mTarget = mBuilder->GetDevice()->CreateRenderTarget(size.Size()); - mArea = area; - mTexture = mTarget->GetTexture(); -} - -void -MaskCombineOperation::PrepareForRendering() -{ - for (const auto& entry : mTextures) { - Rect texCoords = TextureRectToCoords(entry.mRect, entry.mSource->GetSize()); - - SharedVertexBuffer* shared = mBuilder->GetDevice()->GetSharedVertexBuffer(); - - VertexBufferSection section; - if (!shared->Allocate(§ion, 1, sizeof(texCoords), &texCoords)) { - continue; - } - mInputBuffers.push_back(section); - } -} - -void -MaskCombineOperation::Render() -{ - RefPtr device = mBuilder->GetDevice(); - - device->SetTopology(MLGPrimitiveTopology::UnitQuad); - device->SetVertexShader(VertexShaderID::MaskCombiner); - - device->SetPixelShader(PixelShaderID::MaskCombiner); - device->SetSamplerMode(0, SamplerMode::LinearClamp); - device->SetBlendState(MLGBlendState::Min); - - // Since the mask operation is effectively an AND operation, we initialize - // the entire r-channel to 1. - device->Clear(mTarget, Color(1, 0, 0, 1)); - device->SetScissorRect(Nothing()); - device->SetRenderTarget(mTarget); - device->SetViewport(IntRect(IntPoint(0, 0), mTarget->GetSize())); - - for (size_t i = 0; i < mInputBuffers.size(); i++) { - if (!mInputBuffers[i].IsValid()) { - continue; - } - device->SetVertexBuffer(1, &mInputBuffers[i]); - device->SetPSTexture(0, mTextures[i].mSource); - device->DrawInstanced(4, mInputBuffers[i].NumVertices(), 0, 0); - } -} - -void -AppendToMaskTextureList(MaskTextureList& aList, Layer* aLayer) -{ - RefPtr source = GetMaskLayerTexture(aLayer); - if (!source) { - return; - } - - gfx::Rect rect = ComputeQuadForMaskLayer(aLayer, source->GetSize()); - aList.push_back(MaskTexture(rect, source)); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/MaskOperation.h b/gfx/layers/mlgpu/MaskOperation.h deleted file mode 100644 index 47d627606636..000000000000 --- a/gfx/layers/mlgpu/MaskOperation.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_MaskOperation_h -#define mozilla_gfx_layers_mlgpu_MaskOperation_h - -#include "mozilla/RefPtr.h" -#include "mozilla/gfx/Rect.h" -#include "SharedBufferMLGPU.h" -#include - -namespace mozilla { -namespace layers { - -class FrameBuilder; -class Layer; -class MLGDevice; -class MLGRenderTarget; -class MLGTexture; -class TextureSource; - -class MaskOperation -{ - NS_INLINE_DECL_REFCOUNTING(MaskOperation) - -public: - // For when the exact texture is known ahead of time. - MaskOperation(FrameBuilder* aBuilder, MLGTexture* aSource); - - // Return the mask rectangle in screen coordinates. This function takes a - // layer because a single-texture mask operation is not dependent on a - // specific mask transform. (Multiple mask layer operations are, and they - // ignore the layer parameter). - virtual gfx::Rect ComputeMaskRect(Layer* aLayer) const; - - MLGTexture* GetTexture() const { - return mTexture; - } - -protected: - explicit MaskOperation(FrameBuilder* aBuilder); - virtual ~MaskOperation(); - -protected: - RefPtr mTexture; -}; - -struct MaskTexture -{ - MaskTexture() : mSource(nullptr) - {} - MaskTexture(const gfx::Rect& aRect, TextureSource* aSource) - : mRect(aRect), mSource(aSource) - {} - - bool operator <(const MaskTexture& aOther) const; - - gfx::Rect mRect; - RefPtr mSource; -}; - -typedef std::vector MaskTextureList; - -class MaskCombineOperation final : public MaskOperation -{ -public: - explicit MaskCombineOperation(FrameBuilder* aBuilder); - ~MaskCombineOperation() override; - - void Init(const MaskTextureList& aTextures); - - void PrepareForRendering(); - void Render(); - - gfx::Rect ComputeMaskRect(Layer* aLayer) const override { - return mArea; - } - -private: - FrameBuilder* mBuilder; - gfx::Rect mArea; - MaskTextureList mTextures; - RefPtr mTarget; - - std::vector mInputBuffers; -}; - -RefPtr GetMaskLayerTexture(Layer* aLayer); -void AppendToMaskTextureList(MaskTextureList& aList, Layer* aLayer); - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_MaskOperation_h diff --git a/gfx/layers/mlgpu/PaintedLayerMLGPU.cpp b/gfx/layers/mlgpu/PaintedLayerMLGPU.cpp deleted file mode 100644 index b9c8b387e97c..000000000000 --- a/gfx/layers/mlgpu/PaintedLayerMLGPU.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PaintedLayerMLGPU.h" -#include "LayerManagerMLGPU.h" -#include "mozilla/layers/LayersHelpers.h" - -namespace mozilla { - -using namespace gfx; - -namespace layers { - -PaintedLayerMLGPU::PaintedLayerMLGPU(LayerManagerMLGPU* aManager) - : PaintedLayer(aManager, static_cast(this)), - LayerMLGPU(aManager) -{ - MOZ_COUNT_CTOR(PaintedLayerMLGPU); -} - -PaintedLayerMLGPU::~PaintedLayerMLGPU() -{ - MOZ_COUNT_DTOR(PaintedLayerMLGPU); - - CleanupResources(); -} - -bool -PaintedLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder) -{ - if (!mHost) { - return false; - } - - mTexture = mHost->AcquireTextureSource(); - if (!mTexture) { - return false; - } - mTextureOnWhite = mHost->AcquireTextureSourceOnWhite(); - -#ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE - // Note: we don't set PaintWillResample on our ContentTextureHost. The old - // compositor must do this since ContentHost is responsible for issuing - // draw calls, but in AL we can handle it directly here. - // - // Note that when AL performs CPU-based occlusion culling (the default - // behavior), we might break up the visible region again. If that turns - // out to be a problem, we can factor this into ForEachDrawRect instead. - if (MayResample()) { - LayerIntRegion visible = Move(GetShadowVisibleRegion()); - visible = visible.GetBounds(); - SetShadowVisibleRegion(Move(visible)); - } -#endif - return true; -} - -bool -PaintedLayerMLGPU::SetCompositableHost(CompositableHost* aHost) -{ - switch (aHost->GetType()) { - case CompositableType::CONTENT_SINGLE: - case CompositableType::CONTENT_DOUBLE: - mHost = static_cast(aHost)->AsContentHostTexture(); - if (!mHost) { - gfxWarning() << "ContentHostBase is not a ContentHostTexture"; - } - return true; - default: - return false; - } -} - -CompositableHost* -PaintedLayerMLGPU::GetCompositableHost() -{ - return mHost; -} - -void -PaintedLayerMLGPU::CleanupResources() -{ - if (mHost) { - mHost->Detach(this); - } - mTexture = nullptr; - mTextureOnWhite = nullptr; - mHost = nullptr; -} - -void -PaintedLayerMLGPU::PrintInfo(std::stringstream& aStream, const char* aPrefix) -{ - PaintedLayer::PrintInfo(aStream, aPrefix); - if (mHost && mHost->IsAttached()) { - aStream << "\n"; - nsAutoCString pfx(aPrefix); - pfx += " "; - mHost->PrintInfo(aStream, pfx.get()); - } -} - -void -PaintedLayerMLGPU::Disconnect() -{ - CleanupResources(); -} - -bool -PaintedLayerMLGPU::IsContentOpaque() -{ - return !!(GetContentFlags() & CONTENT_OPAQUE); -} - -void -PaintedLayerMLGPU::CleanupCachedResources() -{ - CleanupResources(); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/PaintedLayerMLGPU.h b/gfx/layers/mlgpu/PaintedLayerMLGPU.h deleted file mode 100644 index a0e6602572e6..000000000000 --- a/gfx/layers/mlgpu/PaintedLayerMLGPU.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MOZILLA_GFX_PAINTEDLAYERMLGPU_H -#define MOZILLA_GFX_PAINTEDLAYERMLGPU_H - -#include "LayerManagerMLGPU.h" -#include "mozilla/layers/ContentHost.h" -#include "nsRegionFwd.h" -#include - -namespace mozilla { -namespace layers { - -class PaintedLayerMLGPU final - : public PaintedLayer, - public LayerMLGPU -{ -public: - explicit PaintedLayerMLGPU(LayerManagerMLGPU* aManager); - ~PaintedLayerMLGPU() override; - - // Layer - HostLayer* AsHostLayer() override { return this; } - PaintedLayerMLGPU* AsPaintedLayerMLGPU() override { return this; } - virtual Layer* GetLayer() override { return this; } - bool SetCompositableHost(CompositableHost*) override; - CompositableHost* GetCompositableHost() override; - void Disconnect() override; - bool IsContentOpaque() override; - - // PaintedLayer - void InvalidateRegion(const nsIntRegion& aRegion) override { - MOZ_CRASH("PaintedLayerMLGPU can't fill invalidated regions"); - } - - bool HasComponentAlpha() const { - return !!mTextureOnWhite; - } - TextureSource* GetTexture() const { - return mTexture; - } - TextureSource* GetTextureOnWhite() const { - MOZ_ASSERT(HasComponentAlpha()); - return mTextureOnWhite; - } - - ContentHostTexture* GetContentHost() const { - return mHost; - } - - nsIntRegion GetRenderRegion() const { - nsIntRegion region = GetShadowVisibleRegion().ToUnknownRegion(); - region.AndWith(gfx::IntRect(region.GetBounds().TopLeft(), mTexture->GetSize())); - return region; - } - - MOZ_LAYER_DECL_NAME("PaintedLayerMLGPU", TYPE_PAINTED) - - void CleanupCachedResources(); - -protected: - void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; - bool OnPrepareToRender(FrameBuilder* aBuilder) override; - void ComputeDrawRegion(); - - void CleanupResources(); - -private: - RefPtr mHost; - RefPtr mTexture; - RefPtr mTextureOnWhite; - gfx::IntRegion mLocalDrawRegion; - gfx::IntRegion mTextureRegion; - bool mComputedDrawRegion; -}; - -} // namespace layers -} // namespace mozilla - -#endif diff --git a/gfx/layers/mlgpu/RenderPassMLGPU.cpp b/gfx/layers/mlgpu/RenderPassMLGPU.cpp deleted file mode 100644 index 834af03d277c..000000000000 --- a/gfx/layers/mlgpu/RenderPassMLGPU.cpp +++ /dev/null @@ -1,1010 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "RenderPassMLGPU.h" -#include "ContainerLayerMLGPU.h" -#include "FrameBuilder.h" -#include "ImageLayerMLGPU.h" -#include "LayersLogging.h" -#include "MaskOperation.h" -#include "MLGDevice.h" -#include "PaintedLayerMLGPU.h" -#include "RenderViewMLGPU.h" -#include "ShaderDefinitionsMLGPU.h" -#include "ShaderDefinitionsMLGPU-inl.h" -#include "SharedBufferMLGPU.h" -#include "mozilla/layers/LayersHelpers.h" -#include "mozilla/layers/LayersMessages.h" - -namespace mozilla { -namespace layers { - -using namespace gfx; - -ItemInfo::ItemInfo(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - LayerMLGPU* aLayer, - int32_t aSortOrder, - const IntRect& aBounds, - Maybe&& aGeometry) - : view(aView), - layer(aLayer), - type(RenderPassType::Unknown), - layerIndex(kInvalidResourceIndex), - sortOrder(aSortOrder), - bounds(aBounds), - geometry(Move(aGeometry)) -{ - const Matrix4x4& transform = aLayer->GetLayer()->GetEffectiveTransform(); - - Matrix transform2D; - if (!geometry && - transform.Is2D(&transform2D) && - transform2D.IsRectilinear()) - { - this->rectilinear = true; - if (transform2D.IsIntegerTranslation()) { - this->translation = Some(IntPoint::Truncate(transform2D.GetTranslation())); - } - } else { - this->rectilinear = false; - } - - // Layers can have arbitrary clips or transforms, and we can't use built-in - // scissor functionality when batching. Instead, pixel shaders will write - // transparent pixels for positions outside of the clip. Unfortunately that - // breaks z-buffering because the transparent pixels will still write to - // the depth buffer. - // - // To make this work, we clamp the final vertices in the vertex shader to - // the clip rect. We can only do this for rectilinear transforms. If a - // transform can produce a rotation or perspective change, then we might - // accidentally change the geometry. These items are not treated as - // opaque. - // - // Also, we someday want non-rectilinear items to be antialiased with DEAA, - // and we can't do this if the items are rendered front-to-back, since - // such items cannot be blended. (Though we could consider adding these - // items in two separate draw calls, one for DEAA and for not - that is - // definitely future work.) - if (aLayer->GetComputedOpacity() != 1.0f || - aLayer->GetMask() || - !aLayer->IsContentOpaque() || - !rectilinear) - { - this->opaque = false; - this->renderOrder = RenderOrder::BackToFront; - } else { - this->opaque = true; - this->renderOrder = aView->HasDepthBuffer() - ? RenderOrder::FrontToBack - : RenderOrder::BackToFront; - } - - this->type = RenderPassMLGPU::GetPreferredPassType(aBuilder, *this); -} - -RenderPassType -RenderPassMLGPU::GetPreferredPassType(FrameBuilder* aBuilder, const ItemInfo& aItem) -{ - LayerMLGPU* layer = aItem.layer; - switch (layer->GetType()) { - case Layer::TYPE_COLOR: - { - if (aBuilder->GetDevice()->CanUseClearView() && - aItem.HasRectTransformAndClip() && - aItem.translation && - aItem.opaque && - !aItem.view->HasDepthBuffer()) - { - // Note: we don't have ClearView set up to do depth buffer writes, so we - // exclude depth buffering from the test above. - return RenderPassType::ClearView; - } - return RenderPassType::SolidColor; - } - case Layer::TYPE_PAINTED: { - PaintedLayerMLGPU* painted = layer->AsPaintedLayerMLGPU(); - if (painted->HasComponentAlpha()) { - return RenderPassType::ComponentAlpha; - } - return RenderPassType::SingleTexture; - } - case Layer::TYPE_CANVAS: - return RenderPassType::SingleTexture; - case Layer::TYPE_IMAGE: { - ImageHost* host = layer->AsTexturedLayerMLGPU()->GetImageHost(); - TextureHost* texture = host->CurrentTextureHost(); - if (texture->GetReadFormat() == SurfaceFormat::YUV || - texture->GetReadFormat() == SurfaceFormat::NV12) - { - return RenderPassType::Video; - } - return RenderPassType::SingleTexture; - } - case Layer::TYPE_CONTAINER: - return RenderPassType::RenderView; - default: - return RenderPassType::Unknown; - } -} - -RefPtr -RenderPassMLGPU::CreatePass(FrameBuilder* aBuilder, const ItemInfo& aItem) -{ - switch (aItem.type) { - case RenderPassType::SolidColor: - return MakeAndAddRef(aBuilder, aItem); - case RenderPassType::SingleTexture: - return MakeAndAddRef(aBuilder, aItem); - case RenderPassType::RenderView: - return MakeAndAddRef(aBuilder, aItem); - case RenderPassType::Video: - return MakeAndAddRef(aBuilder, aItem); - case RenderPassType::ComponentAlpha: - return MakeAndAddRef(aBuilder, aItem); - case RenderPassType::ClearView: - return MakeAndAddRef(aBuilder, aItem); - default: - return nullptr; - } -} - -RenderPassMLGPU::RenderPassMLGPU(FrameBuilder* aBuilder, const ItemInfo& aItem) - : mBuilder(aBuilder), - mDevice(aBuilder->GetDevice()), - mLayerBufferIndex(aBuilder->CurrentLayerBufferIndex()), - mMaskRectBufferIndex(kInvalidResourceIndex), - mPrepared(false) -{ -} - -RenderPassMLGPU::~RenderPassMLGPU() -{ -} - -bool -RenderPassMLGPU::IsCompatible(const ItemInfo& aItem) -{ - if (GetType() != aItem.type) { - return false; - } - if (mLayerBufferIndex != mBuilder->CurrentLayerBufferIndex()) { - return false; - } - return true; -} - -bool -RenderPassMLGPU::AcceptItem(ItemInfo& aInfo) -{ - MOZ_ASSERT(IsCompatible(aInfo)); - - if (!AddToPass(aInfo.layer, aInfo)) { - return false; - } - - if (aInfo.renderOrder == RenderOrder::BackToFront) { - mAffectedRegion.OrWith(aInfo.bounds); - mAffectedRegion.SimplifyOutward(4); - } - return true; -} - -bool -RenderPassMLGPU::Intersects(const ItemInfo& aItem) -{ - MOZ_ASSERT(aItem.renderOrder == RenderOrder::BackToFront); - return !mAffectedRegion.Intersect(aItem.bounds).IsEmpty(); -} - -void -RenderPassMLGPU::PrepareForRendering() -{ - mPrepared = true; -} - -ShaderRenderPass::ShaderRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem) - : RenderPassMLGPU(aBuilder, aItem), - mGeometry(GeometryMode::Unknown), - mHasRectTransformAndClip(aItem.HasRectTransformAndClip()), - mItems(mDevice) -{ - mMask = aItem.layer->GetMask(); - if (mMask) { - mMaskRectBufferIndex = mBuilder->CurrentMaskRectBufferIndex(); - } -} - -bool -ShaderRenderPass::IsCompatible(const ItemInfo& aItem) -{ - MOZ_ASSERT(mGeometry != GeometryMode::Unknown); - - if (!RenderPassMLGPU::IsCompatible(aItem)) { - return false; - } - - // A masked batch cannot accept non-masked items, since the pixel shader - // bakes in whether a mask is present. Also, the pixel shader can only bind - // one specific mask at a time. - if (aItem.layer->GetMask() != mMask) { - return false; - } - if (mMask && mBuilder->CurrentMaskRectBufferIndex() != mMaskRectBufferIndex) { - return false; - } - - // We key batches on this property, since we can use more efficient pixel - // shaders if we don't need to propagate a clip and a mask. - if (mHasRectTransformAndClip != aItem.HasRectTransformAndClip()) { - return false; - } - - // We should be assured at this point, that if the item requires complex - // geometry, then it should have already been rejected from a unit-quad - // batch. Therefore this batch should be in polygon mode. - MOZ_ASSERT_IF(aItem.geometry.isSome(), mGeometry == GeometryMode::Polygon); - return true; -} - -void -ShaderRenderPass::SetGeometry(const ItemInfo& aItem, GeometryMode aMode) -{ - MOZ_ASSERT(mGeometry == GeometryMode::Unknown); - - if (aMode == GeometryMode::Unknown) { - mGeometry = mHasRectTransformAndClip - ? GeometryMode::UnitQuad - : GeometryMode::Polygon; - } else { - mGeometry = aMode; - } - - // Since we process layers front-to-back, back-to-front items are - // in the wrong order. We address this by automatically reversing - // the buffers we use to build vertices. - if (aItem.renderOrder != RenderOrder::FrontToBack) { - mVertices.SetReversed(); - mInstances.SetReversed(); - - // For arbitrary geometry items, each vertex explicitly indexes into - // the constant buffer, and so we must preserve the association it - // created. However for normal unit-quad items, the constant buffer - // order must match the vertex order. - if (mGeometry != GeometryMode::Polygon) { - mItems.SetReversed(); - } - } -} - -void -ShaderRenderPass::PrepareForRendering() -{ - if (mItems.IsEmpty()) { - return; - } - if (!mVertices.IsEmpty()) { - if (!PrepareVertexBuffer()) { - return; - } - } else { - if (!PrepareInstanceBuffer()) { - return; - } - } - if (!PrepareItemBuffer() || - !SetupPSBuffer0(GetOpacity()) || - !OnPrepareBuffers()) - { - return; - } - return RenderPassMLGPU::PrepareForRendering(); -} - -bool -ShaderRenderPass::PrepareVertexBuffer() -{ - // Geometry batches always build vertices, and do not have an instance buffer. - MOZ_ASSERT(!mVertices.IsEmpty()); - MOZ_ASSERT(mGeometry == GeometryMode::Polygon); - MOZ_ASSERT(mInstances.IsEmpty()); - - return mDevice->GetSharedVertexBuffer()->Allocate(&mVertexBuffer, mVertices); -} - -bool -ShaderRenderPass::PrepareInstanceBuffer() -{ - // We should not be using the polygon vertex buffer, and we should have - // added items. - MOZ_ASSERT(mVertices.IsEmpty()); - MOZ_ASSERT(mGeometry == GeometryMode::UnitQuad); - MOZ_ASSERT(!mInstances.IsEmpty()); - - return mDevice->GetSharedVertexBuffer()->Allocate(&mInstanceBuffer, mInstances); -} - -bool -ShaderRenderPass::PrepareItemBuffer() -{ - return mDevice->GetSharedVSBuffer()->Allocate(&mItemBuffer, mItems); -} - -bool -ShaderRenderPass::SetupPSBuffer0(float aOpacity) -{ - if (aOpacity == 1.0f && !HasMask()) { - mPSBuffer0 = mBuilder->GetDefaultMaskInfo(); - return true; - } - - MaskInformation cb(aOpacity, HasMask()); - return mDevice->GetSharedPSBuffer()->Allocate(&mPSBuffer0, cb); -} - -void -ShaderRenderPass::ExecuteRendering() -{ - mDevice->SetPSConstantBuffer(0, &mPSBuffer0); - if (MaskOperation* mask = GetMask()) { - mDevice->SetPSTexture(kMaskLayerTextureSlot, mask->GetTexture()); - mDevice->SetSamplerMode(kMaskSamplerSlot, SamplerMode::LinearClampToZero); - } - - SetupPipeline(); - - if (mGeometry == GeometryMode::Polygon) { - mDevice->SetTopology(MLGPrimitiveTopology::TriangleList); - mDevice->SetVertexBuffer(0, &mVertexBuffer); - } else { - mDevice->SetTopology(MLGPrimitiveTopology::UnitQuad); - mDevice->SetVertexBuffer(1, &mInstanceBuffer); - } - - mDevice->SetVSConstantBuffer(kItemBufferSlot, &mItemBuffer); - - if (mGeometry == GeometryMode::Polygon) { - mDevice->Draw(mVertexBuffer.NumVertices(), 0); - } else { - mDevice->DrawInstanced(4, mItemBuffer.NumItems(), 0, 0); - } -} - -static inline Color -ComputeLayerColor(LayerMLGPU* aLayer, const Color& aColor) -{ - float opacity = aLayer->GetComputedOpacity(); - return Color( - aColor.r * aColor.a * opacity, - aColor.g * aColor.a * opacity, - aColor.b * aColor.a * opacity, - aColor.a * opacity); -} - -ClearViewPass::ClearViewPass(FrameBuilder* aBuilder, const ItemInfo& aItem) - : RenderPassMLGPU(aBuilder, aItem), - mView(aItem.view) -{ - // Note: we could write to the depth buffer, but since the depth buffer is - // disabled by default, we don't bother yet. - MOZ_ASSERT(!mView->HasDepthBuffer()); - - ColorLayer* colorLayer = aItem.layer->GetLayer()->AsColorLayer(); - mColor = ComputeLayerColor(aItem.layer, colorLayer->GetColor()); -} - -bool -ClearViewPass::IsCompatible(const ItemInfo& aItem) -{ - if (!RenderPassMLGPU::IsCompatible(aItem)) { - return false; - } - - // These should be true if we computed a ClearView pass type. - MOZ_ASSERT(aItem.translation); - MOZ_ASSERT(aItem.opaque); - MOZ_ASSERT(aItem.HasRectTransformAndClip()); - - // Each call only supports a single color. - ColorLayer* colorLayer = aItem.layer->GetLayer()->AsColorLayer(); - if (mColor != ComputeLayerColor(aItem.layer, colorLayer->GetColor())) { - return false; - } - - // We don't support opacity here since it would not blend correctly. - MOZ_ASSERT(mColor.a == 1.0f); - return true; -} - -bool -ClearViewPass::AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) -{ - const LayerIntRegion& region = aItem->GetShadowVisibleRegion(); - for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) { - IntRect rect = iter.Get().ToUnknownRect(); - rect += aInfo.translation.value(); - rect -= mView->GetTargetOffset(); - mRects.AppendElement(rect); - } - return true; -} - -void -ClearViewPass::ExecuteRendering() -{ - mDevice->ClearView(mDevice->GetRenderTarget(), mColor, mRects.Elements(), mRects.Length()); -} - -SolidColorPass::SolidColorPass(FrameBuilder* aBuilder, const ItemInfo& aItem) - : BatchRenderPass(aBuilder, aItem) -{ - SetDefaultGeometry(aItem); -} - -bool -SolidColorPass::AddToPass(LayerMLGPU* aLayer, ItemInfo& aInfo) -{ - MOZ_ASSERT(aLayer->GetType() == Layer::TYPE_COLOR); - - ColorLayer* colorLayer = aLayer->GetLayer()->AsColorLayer(); - - Txn txn(this); - - gfx::Color color = ComputeLayerColor(aLayer, colorLayer->GetColor()); - - const LayerIntRegion& region = aLayer->GetShadowVisibleRegion(); - for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) { - const IntRect rect = iter.Get().ToUnknownRect(); - ColorTraits traits(Rect(rect), color); - - if (!txn.Add(traits, aInfo)) { - return false; - } - } - return txn.Commit(); -} - -float -SolidColorPass::GetOpacity() const -{ - // Note our pixel shader just ignores the opacity, since we baked it - // into our color values already. Just return 1, which ensures we can - // use the default constant buffer binding. - return 1.0f; -} - -void -SolidColorPass::SetupPipeline() -{ - if (mGeometry == GeometryMode::UnitQuad) { - mDevice->SetVertexShader(VertexShaderID::ColoredQuad); - mDevice->SetPixelShader(PixelShaderID::ColoredQuad); - } else { - mDevice->SetVertexShader(VertexShaderID::ColoredVertex); - mDevice->SetPixelShader(PixelShaderID::ColoredVertex); - } -} - -TexturedRenderPass::TexturedRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem) - : BatchRenderPass(aBuilder, aItem), - mTextureFlags(TextureFlags::NO_FLAGS) -{ -} - -bool -TexturedRenderPass::AddItem(Txn& aTxn, - const ItemInfo& aInfo, - const Rect& aDrawRect, - const Point& aDestOrigin, - const IntSize& aTextureSize, - const Maybe& aScale) -{ - - if (mGeometry == GeometryMode::Polygon) { - // This path will not clamp the draw rect to the layer clip, so we can pass - // the draw rect texture rects straight through. - return AddClippedItem(aTxn, aInfo, aDrawRect, aDestOrigin, aTextureSize, aScale); - } - - MOZ_ASSERT(!aInfo.geometry); - MOZ_ASSERT(aInfo.HasRectTransformAndClip()); - MOZ_ASSERT(mHasRectTransformAndClip); - - const Matrix4x4& fullTransform = aInfo.layer->GetLayer()->GetEffectiveTransformForBuffer(); - Matrix transform = fullTransform.As2D(); - Matrix inverse = transform.Inverse(); - MOZ_ASSERT(inverse.IsRectilinear()); - - // Transform the clip rect. - IntRect clipRect = aInfo.layer->GetComputedClipRect().ToUnknownRect(); - clipRect += aInfo.view->GetTargetOffset(); - - // Clip and adjust the texture rect. - Rect localClip = inverse.TransformBounds(Rect(clipRect)); - Rect clippedDrawRect = aDrawRect.Intersect(localClip); - if (clippedDrawRect.IsEmpty()) { - return true; - } - - return AddClippedItem(aTxn, aInfo, clippedDrawRect, aDestOrigin, aTextureSize, aScale); -} - -bool -TexturedRenderPass::AddClippedItem(Txn& aTxn, - const ItemInfo& aInfo, - const gfx::Rect& aDrawRect, - const gfx::Point& aDestOrigin, - const gfx::IntSize& aTextureSize, - const Maybe& aScale) -{ - float xScale = aScale ? aScale->width : 1.0f; - float yScale = aScale ? aScale->height : 1.0f; - - Point offset = aDrawRect.TopLeft() - aDestOrigin; - Rect textureRect( - offset.x * xScale, - offset.y * yScale, - aDrawRect.width * xScale, - aDrawRect.height * yScale); - - Rect textureCoords = TextureRectToCoords(textureRect, aTextureSize); - if (mTextureFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) { - textureCoords.y = textureCoords.YMost(); - textureCoords.height = -textureCoords.height; - } - - Rect layerRects[4]; - Rect textureRects[4]; - size_t numRects = - DecomposeIntoNoRepeatRects(aDrawRect, textureCoords, &layerRects, &textureRects); - - for (size_t i = 0; i < numRects; i++) { - TexturedTraits traits(layerRects[i], textureRects[i]); - if (!aTxn.Add(traits, aInfo)) { - return false; - } - } - return true; -} - -SingleTexturePass::SingleTexturePass(FrameBuilder* aBuilder, const ItemInfo& aItem) - : TexturedRenderPass(aBuilder, aItem), - mOpacity(1.0f) -{ - SetDefaultGeometry(aItem); -} - -bool -SingleTexturePass::AddToPass(LayerMLGPU* aLayer, ItemInfo& aInfo) -{ - RefPtr texture; - - gfx::SamplingFilter filter; - TextureFlags flags = TextureFlags::NO_FLAGS; - if (PaintedLayerMLGPU* paintedLayer = aLayer->AsPaintedLayerMLGPU()) { - if (paintedLayer->HasComponentAlpha()) { - return false; - } - texture = paintedLayer->GetTexture(); - filter = SamplingFilter::LINEAR; - } else if (TexturedLayerMLGPU* texLayer = aLayer->AsTexturedLayerMLGPU()) { - texture = texLayer->GetTexture(); - filter = texLayer->GetSamplingFilter(); - TextureHost* host = texLayer->GetImageHost()->CurrentTextureHost(); - flags = host->GetFlags(); - } else { - return false; - } - - // We should not assign a texture-based layer to tiles if it has no texture. - MOZ_ASSERT(texture); - - float opacity = aLayer->GetComputedOpacity(); - if (mTexture) { - if (texture != mTexture) { - return false; - } - if (mFilter != filter) { - return false; - } - if (mOpacity != opacity) { - return false; - } - // Note: premultiplied, origin-bottom-left are already implied by the texture source. - } else { - mTexture = texture; - mFilter = filter; - mOpacity = opacity; - mTextureFlags = flags; - } - - Txn txn(this); - - if (PaintedLayerMLGPU* layer = aLayer->AsPaintedLayerMLGPU()) { - nsIntRegion visible = layer->GetRenderRegion(); - IntPoint offset = layer->GetContentHost()->GetOriginOffset(); - - if (!AddItems(txn, aInfo, visible, offset, mTexture->GetSize())) { - return false; - } - } else if (TexturedLayerMLGPU* layer = aLayer->AsTexturedLayerMLGPU()) { - IntPoint origin(0, 0); - Maybe pictureScale = layer->GetPictureScale(); - nsIntRegion visible = layer->GetShadowVisibleRegion().ToUnknownRegion(); - - if (!AddItems(txn, aInfo, visible, origin, mTexture->GetSize(), pictureScale)) { - return false; - } - } - - return txn.Commit(); -} - -Maybe -SingleTexturePass::GetBlendState() const -{ - return (mTextureFlags & TextureFlags::NON_PREMULTIPLIED) - ? Some(MLGBlendState::OverAndPremultiply) - : Some(MLGBlendState::Over); -} - -void -SingleTexturePass::SetupPipeline() -{ - MOZ_ASSERT(mTexture); - - if (mGeometry == GeometryMode::UnitQuad) { - mDevice->SetVertexShader(VertexShaderID::TexturedQuad); - } else { - mDevice->SetVertexShader(VertexShaderID::TexturedVertex); - } - - mDevice->SetPSTexture(0, mTexture); - mDevice->SetSamplerMode(kDefaultSamplerSlot, mFilter); - switch (mTexture.get()->GetFormat()) { - case SurfaceFormat::B8G8R8A8: - case SurfaceFormat::R8G8B8A8: - if (mGeometry == GeometryMode::UnitQuad) - mDevice->SetPixelShader(PixelShaderID::TexturedQuadRGBA); - else - mDevice->SetPixelShader(PixelShaderID::TexturedVertexRGBA); - break; - default: - if (mGeometry == GeometryMode::UnitQuad) - mDevice->SetPixelShader(PixelShaderID::TexturedQuadRGB); - else - mDevice->SetPixelShader(PixelShaderID::TexturedVertexRGB); - break; - } -} - -ComponentAlphaPass::ComponentAlphaPass(FrameBuilder* aBuilder, const ItemInfo& aItem) -: TexturedRenderPass(aBuilder, aItem), - mAssignedLayer(nullptr) -{ - SetDefaultGeometry(aItem); -} - -bool -ComponentAlphaPass::AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) -{ - PaintedLayerMLGPU* layer = aItem->AsPaintedLayerMLGPU(); - MOZ_ASSERT(layer); - - if (mAssignedLayer && mAssignedLayer != layer) { - return false; - } - if (!mAssignedLayer) { - mAssignedLayer = layer; - mTextureOnBlack = layer->GetTexture(); - mTextureOnWhite = layer->GetTextureOnWhite(); - } - - Txn txn(this); - - nsIntRegion visible = layer->GetRenderRegion(); - IntPoint offset = layer->GetContentHost()->GetOriginOffset(); - - if (!AddItems(txn, aInfo, visible, offset, mTextureOnWhite->GetSize())) { - return false; - } - return txn.Commit(); -} - -float -ComponentAlphaPass::GetOpacity() const -{ - return mAssignedLayer->GetComputedOpacity(); -} - -void -ComponentAlphaPass::SetupPipeline() -{ - TextureSource* textures[2] = { - mTextureOnBlack, - mTextureOnWhite - }; - MOZ_ASSERT(textures[0]); - MOZ_ASSERT(textures[1]); - - if (mGeometry == GeometryMode::UnitQuad) { - mDevice->SetVertexShader(VertexShaderID::TexturedQuad); - mDevice->SetPixelShader(PixelShaderID::ComponentAlphaQuad); - } else { - mDevice->SetVertexShader(VertexShaderID::TexturedVertex); - mDevice->SetPixelShader(PixelShaderID::ComponentAlphaVertex); - } - - mDevice->SetSamplerMode(kDefaultSamplerSlot, SamplerMode::LinearClamp); - mDevice->SetPSTextures(0, 2, textures); -} - -VideoRenderPass::VideoRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem) - : TexturedRenderPass(aBuilder, aItem), - mOpacity(1.0f) -{ - SetDefaultGeometry(aItem); -} - -bool -VideoRenderPass::AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) -{ - ImageLayerMLGPU* layer = aItem->AsImageLayerMLGPU(); - if (!layer) { - return false; - } - - RefPtr host = layer->GetImageHost()->CurrentTextureHost(); - RefPtr source = layer->GetTexture(); - float opacity = layer->GetComputedOpacity(); - SamplingFilter filter = layer->GetSamplingFilter(); - - if (mHost) { - if (mHost != host) { - return false; - } - if (mTexture != source) { - return false; - } - if (mOpacity != opacity) { - return false; - } - if (mFilter != filter) { - return false; - } - } else { - mHost = host; - mTexture = source; - mOpacity = opacity; - mFilter = filter; - } - MOZ_ASSERT(!mTexture->AsBigImageIterator()); - MOZ_ASSERT(!(mHost->GetFlags() & TextureFlags::NON_PREMULTIPLIED)); - MOZ_ASSERT(!(mHost->GetFlags() & TextureFlags::ORIGIN_BOTTOM_LEFT)); - - Txn txn(this); - - IntPoint origin(0, 0); - Maybe pictureScale = layer->GetPictureScale(); - nsIntRegion visible = layer->GetShadowVisibleRegion().ToUnknownRegion(); - - if (!AddItems(txn, aInfo, visible, origin, mTexture->GetSize(), pictureScale)) { - return false; - } - return txn.Commit(); -} - -void -VideoRenderPass::SetupPipeline() -{ - YUVColorSpace colorSpace = YUVColorSpace::UNKNOWN; - switch (mHost->GetReadFormat()) { - case SurfaceFormat::YUV: { - colorSpace = mHost->GetYUVColorSpace(); - break; - } - case SurfaceFormat::NV12: - colorSpace = YUVColorSpace::BT601; - break; - default: - MOZ_ASSERT_UNREACHABLE("Unexpected surface format in VideoRenderPass"); - break; - } - MOZ_ASSERT(colorSpace != YUVColorSpace::UNKNOWN); - - RefPtr ps1 = mDevice->GetBufferForColorSpace(colorSpace); - if (!ps1) { - return; - } - - if (mGeometry == GeometryMode::UnitQuad) { - mDevice->SetVertexShader(VertexShaderID::TexturedQuad); - } else { - mDevice->SetVertexShader(VertexShaderID::TexturedVertex); - } - - switch (mHost->GetReadFormat()) { - case SurfaceFormat::YUV: - { - if (mGeometry == GeometryMode::UnitQuad) - mDevice->SetPixelShader(PixelShaderID::TexturedQuadIMC4); - else - mDevice->SetPixelShader(PixelShaderID::TexturedVertexIMC4); - mDevice->SetPSTexturesYUV(0, mTexture); - break; - } - case SurfaceFormat::NV12: - if (mGeometry == GeometryMode::UnitQuad) - mDevice->SetPixelShader(PixelShaderID::TexturedQuadNV12); - else - mDevice->SetPixelShader(PixelShaderID::TexturedVertexNV12); - mDevice->SetPSTexturesNV12(0, mTexture); - break; - default: - MOZ_ASSERT_UNREACHABLE("Unknown video format"); - break; - } - - mDevice->SetSamplerMode(kDefaultSamplerSlot, mFilter); - mDevice->SetPSConstantBuffer(1, ps1); -} - -RenderViewPass::RenderViewPass(FrameBuilder* aBuilder, const ItemInfo& aItem) - : TexturedRenderPass(aBuilder, aItem), - mParentView(nullptr) -{ - mAssignedLayer = aItem.layer->AsContainerLayerMLGPU(); - - CompositionOp blendOp = mAssignedLayer->GetMixBlendMode(); - if (BlendOpIsMixBlendMode(blendOp)) { - mBlendMode = Some(blendOp); - } - - if (mBlendMode) { - // We do not have fast-path rect shaders for blending. - SetGeometry(aItem, GeometryMode::Polygon); - } else { - SetDefaultGeometry(aItem); - } -} - -bool -RenderViewPass::AddToPass(LayerMLGPU* aLayer, ItemInfo& aInfo) -{ - // We bake in the layer ahead of time, which also guarantees the blend mode - // is baked in, as well as the geometry requirement. - if (mAssignedLayer != aLayer) { - return false; - } - - mSource = mAssignedLayer->GetRenderTarget(); - mParentView = aInfo.view; - - Txn txn(this); - - IntPoint offset = mAssignedLayer->GetTargetOffset(); - IntSize size = mAssignedLayer->GetTargetSize(); - - // Clamp the visible region to the texture size. - nsIntRegion visible = mAssignedLayer->GetShadowVisibleRegion().ToUnknownRegion(); - visible.AndWith(IntRect(offset, size)); - - if (!AddItems(txn, aInfo, visible, offset, size)) { - return false; - } - return txn.Commit(); -} - -float -RenderViewPass::GetOpacity() const -{ - return mAssignedLayer->GetLayer()->GetEffectiveOpacity(); -} - -bool -RenderViewPass::OnPrepareBuffers() -{ - if (mBlendMode && !PrepareBlendState()) { - return false; - } - return true; -} - -static inline PixelShaderID -GetShaderForBlendMode(CompositionOp aOp) -{ - switch (aOp) { - case CompositionOp::OP_MULTIPLY: return PixelShaderID::BlendMultiply; - case CompositionOp::OP_SCREEN: return PixelShaderID::BlendScreen; - case CompositionOp::OP_OVERLAY: return PixelShaderID::BlendOverlay; - case CompositionOp::OP_DARKEN: return PixelShaderID::BlendDarken; - case CompositionOp::OP_LIGHTEN: return PixelShaderID::BlendLighten; - case CompositionOp::OP_COLOR_DODGE: return PixelShaderID::BlendColorDodge; - case CompositionOp::OP_COLOR_BURN: return PixelShaderID::BlendColorBurn; - case CompositionOp::OP_HARD_LIGHT: return PixelShaderID::BlendHardLight; - case CompositionOp::OP_SOFT_LIGHT: return PixelShaderID::BlendSoftLight; - case CompositionOp::OP_DIFFERENCE: return PixelShaderID::BlendDifference; - case CompositionOp::OP_EXCLUSION: return PixelShaderID::BlendExclusion; - case CompositionOp::OP_HUE: return PixelShaderID::BlendHue; - case CompositionOp::OP_SATURATION: return PixelShaderID::BlendSaturation; - case CompositionOp::OP_COLOR: return PixelShaderID::BlendColor; - case CompositionOp::OP_LUMINOSITY: return PixelShaderID::BlendLuminosity; - default: - MOZ_ASSERT_UNREACHABLE("Unexpected blend mode"); - return PixelShaderID::TexturedVertexRGBA; - } -} - -bool -RenderViewPass::PrepareBlendState() -{ - Rect visibleRect(mAssignedLayer->GetShadowVisibleRegion().GetBounds().ToUnknownRect()); - IntRect clipRect(mAssignedLayer->GetComputedClipRect().ToUnknownRect()); - const Matrix4x4& transform = mAssignedLayer->GetLayer()->GetEffectiveTransformForBuffer(); - - // Note that we must use our parent RenderView for this calculation, - // since we're copying the backdrop, not our actual local target. - IntRect rtRect(mParentView->GetTargetOffset(), mParentView->GetSize()); - - Matrix4x4 backdropTransform; - mBackdropCopyRect = ComputeBackdropCopyRect( - visibleRect, - clipRect, - transform, - rtRect, - &backdropTransform); - - AutoBufferUpload cb; - if (!mDevice->GetSharedVSBuffer()->Allocate(&mBlendConstants, &cb)) { - return false; - } - memcpy(cb->backdropTransform, &backdropTransform._11, 64); - return true; -} - -void -RenderViewPass::SetupPipeline() -{ - if (mBlendMode) { - RefPtr backdrop = mParentView->GetRenderTarget(); - MOZ_ASSERT(mDevice->GetRenderTarget() == backdrop); - - RefPtr copy = mDevice->CreateTexture( - mBackdropCopyRect.Size(), - SurfaceFormat::B8G8R8A8, - MLGUsage::Default, - MLGTextureFlags::ShaderResource); - if (!copy) { - return; - } - - mDevice->CopyTexture( - copy, - IntPoint(0, 0), - backdrop->GetTexture(), - mBackdropCopyRect); - - MOZ_ASSERT(mGeometry == GeometryMode::Polygon); - mDevice->SetVertexShader(VertexShaderID::BlendVertex); - mDevice->SetPixelShader(GetShaderForBlendMode(mBlendMode.value())); - mDevice->SetVSConstantBuffer(kBlendConstantBufferSlot, &mBlendConstants); - mDevice->SetPSTexture(1, copy); - } else { - if (mGeometry == GeometryMode::UnitQuad) { - mDevice->SetVertexShader(VertexShaderID::TexturedQuad); - mDevice->SetPixelShader(PixelShaderID::TexturedQuadRGBA); - } else { - mDevice->SetVertexShader(VertexShaderID::TexturedVertex); - mDevice->SetPixelShader(PixelShaderID::TexturedVertexRGBA); - } - } - - mDevice->SetPSTexture(0, mSource->GetTexture()); - mDevice->SetSamplerMode(kDefaultSamplerSlot, SamplerMode::LinearClamp); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/RenderPassMLGPU.h b/gfx/layers/mlgpu/RenderPassMLGPU.h deleted file mode 100644 index 4a72c890a4c1..000000000000 --- a/gfx/layers/mlgpu/RenderPassMLGPU.h +++ /dev/null @@ -1,532 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MOZILLA_GFX_RENDERPASSMLGPU_H -#define MOZILLA_GFX_RENDERPASSMLGPU_H - -#include "LayerManagerMLGPU.h" -#include "ShaderDefinitionsMLGPU.h" -#include "SharedBufferMLGPU.h" -#include "StagingBuffer.h" - -namespace mozilla { -namespace layers { - -using namespace mlg; - -class RenderViewMLGPU; - -enum class RenderPassType { - ClearView, - SolidColor, - SingleTexture, - RenderView, - Video, - ComponentAlpha, - Unknown -}; - -enum class RenderOrder -{ - // Used for all items when not using a depth buffer. Otherwise, used for - // items that may draw transparent pixels. - BackToFront, - - // Only used when the depth buffer is enabled, and only for items that are - // guaranteed to only draw opaque pixels. - FrontToBack -}; - -static const uint32_t kInvalidResourceIndex = uint32_t(-1); - -struct ItemInfo { - explicit ItemInfo(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - LayerMLGPU* aLayer, - int32_t aSortOrder, - const gfx::IntRect& aBounds, - Maybe&& aGeometry); - - // Return true if a layer can be clipped by the vertex shader; false - // otherwise. Any kind of textured mask or non-rectilinear transform - // will cause this to return false. - bool HasRectTransformAndClip() const { - return rectilinear && !layer->GetMask(); - } - - RenderViewMLGPU* view; - LayerMLGPU* layer; - RenderPassType type; - uint32_t layerIndex; - int32_t sortOrder; - gfx::IntRect bounds; - RenderOrder renderOrder; - Maybe geometry; - - // Set only when the transform is a 2D integer translation. - Maybe translation; - - // Set when the item bounds will occlude anything below it. - bool opaque; - - // Set when the item's transform is 2D and rectilinear. - bool rectilinear; -}; - -// Base class for anything that can render in a batch to the GPU. -class RenderPassMLGPU -{ - NS_INLINE_DECL_REFCOUNTING(RenderPassMLGPU) - -public: - static RenderPassType GetPreferredPassType(FrameBuilder* aBuilder, - const ItemInfo& aInfo); - - static RefPtr CreatePass(FrameBuilder* aBuilder, - const ItemInfo& aInfo); - - // Return true if this pass is compatible with the given item, false - // otherwise. This does not guarantee the pass will accept the item, - // but does guarantee we can try. - virtual bool IsCompatible(const ItemInfo& aItem); - - virtual RenderPassType GetType() const = 0; - - // Return true if the layer was compatible with and added to this pass, - // false otherwise. - bool AcceptItem(ItemInfo& aInfo); - - // Prepare constants buffers and textures. - virtual void PrepareForRendering(); - - // Execute this render pass to the currently selected surface. - virtual void ExecuteRendering() = 0; - - virtual Maybe GetBlendState() const { - return Nothing(); - } - - size_t GetLayerBufferIndex() const { - return mLayerBufferIndex; - } - Maybe GetMaskRectBufferIndex() const { - return mMaskRectBufferIndex == kInvalidResourceIndex - ? Nothing() - : Some(mMaskRectBufferIndex); - } - - // Returns true if this pass overlaps the affected region of an item. This - // only ever returns true for transparent items and transparent batches, - // and should not be used otherwise. - bool Intersects(const ItemInfo& aItem); - - // Returns true if pass has been successfully prepared. - bool IsPrepared() const { - return mPrepared; - } - -protected: - RenderPassMLGPU(FrameBuilder* aBuilder, const ItemInfo& aItem); - virtual ~RenderPassMLGPU(); - - // Return true if the item was consumed, false otherwise. - virtual bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) = 0; - -protected: - enum class GeometryMode { - Unknown, - UnitQuad, - Polygon - }; - -protected: - FrameBuilder* mBuilder; - RefPtr mDevice; - size_t mLayerBufferIndex; - size_t mMaskRectBufferIndex; - gfx::IntRegion mAffectedRegion; - bool mPrepared; -}; - -// Shader-based render passes execute a draw call, vs. non-shader passes that -// use non-shader APIs (like ClearView). -class ShaderRenderPass : public RenderPassMLGPU -{ -public: - ShaderRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem); - - // Used by ShaderDefinitions for writing traits. - VertexStagingBuffer* GetVertices() { - return &mVertices; - } - VertexStagingBuffer* GetInstances() { - return &mInstances; - } - ConstantStagingBuffer* GetItems() { - return &mItems; - } - - bool IsCompatible(const ItemInfo& aItem) override; - void PrepareForRendering() override; - void ExecuteRendering() override; - - virtual Maybe GetBlendState() const override{ - return Some(MLGBlendState::Over); - } - -protected: - // If this batch has a uniform opacity, return it here. Otherwise this should - // return 1.0. - virtual float GetOpacity() const = 0; - - // Set any components of the pipeline that won't be handled by - // ExecuteRendering. This is called only once even if multiple draw calls - // are issued. - virtual void SetupPipeline() = 0; - -protected: - // Set the geometry this pass will use. This must be called by every - // derived constructor. Use GeometryMode::Unknown to pick the default - // behavior: UnitQuads for rectilinear transform+clips, and polygons - // otherwise. - void SetGeometry(const ItemInfo& aItem, GeometryMode aMode); - - void SetDefaultGeometry(const ItemInfo& aItem) { - SetGeometry(aItem, GeometryMode::Unknown); - } - - // Called after PrepareForRendering() has finished. If this returns false, - // PrepareForRendering() will return false. - virtual bool OnPrepareBuffers() { - return true; - } - - // Prepare the buffer bound to "sItems" in shaders. This is used for opaque - // batches when the items can be drawn in front-to-back order. - bool PrepareItemBuffer(); - - // Prepare the vertex buffer, if not using a unit quad. This is used for - // opaque batches when the items can be drawn in front-to-back order. - bool PrepareVertexBuffer(); - bool PrepareInstanceBuffer(); - - // Prepare the mask/opacity buffer bound in most pixel shaders. - bool SetupPSBuffer0(float aOpacity); - - bool HasMask() const { - return !!mMask; - } - MaskOperation* GetMask() const { - return mMask; - } - -protected: - GeometryMode mGeometry; - RefPtr mMask; - bool mHasRectTransformAndClip; - - VertexStagingBuffer mVertices; - VertexBufferSection mVertexBuffer; - - VertexStagingBuffer mInstances; - VertexBufferSection mInstanceBuffer; - - ConstantStagingBuffer mItems; - ConstantBufferSection mItemBuffer; - - ConstantBufferSection mPSBuffer0; -}; - -// This contains various helper functions for building vertices and shader -// inputs for layers. -template -class BatchRenderPass : public ShaderRenderPass -{ -public: - BatchRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem) - : ShaderRenderPass(aBuilder, aItem) - {} - -protected: - // It is tricky to determine ahead of time whether or not we'll have enough - // room in our buffers to hold all draw commands for a layer, especially - // since layers can have multiple draw rects. We don't want to draw one rect, - // reject the item, then redraw the same rect again in another batch. - // To deal with this we use a transaction approach and reject the transaction - // if we couldn't add everything. - class Txn { - public: - explicit Txn(BatchRenderPass* aPass) - : mPass(aPass), - mPrevVertexPos(aPass->mVertices.GetPosition()), - mPrevItemPos(aPass->mItems.GetPosition()), - mPrevInstancePos(aPass->mInstances.GetPosition()) - {} - - // Add an item based on a draw rect, layer, and optional geometry. The Traits - // must contain, at minimum: - // - // - An "mRect" member as a gfx::Rect, containing the draw rect. - // - An "AddInstanceTo" method, which adds instance data for - // shaders using unit-quad vertices. - // - An "AddVerticesTo" method, which adds triangle list vertices - // to a batch's shader data, with optional geometry. - // - An "AddItemTo" method, which adds constant buffer data if - // needed. - // - bool Add(const Traits& aTraits, const ItemInfo& aInfo) { - // If this succeeds, but we clip the polygon below, that's okay. - // Polygons do not use instanced rendering so this won't break - // ordering. - if (!aTraits.AddItemTo(mPass)) { - return false; - } - - if (mPass->mGeometry == GeometryMode::Polygon) { - size_t itemIndex = mPass->GetItems()->NumItems() - 1; - if (aInfo.geometry) { - gfx::Polygon polygon = aInfo.geometry->ClipPolygon(aTraits.mRect); - if (polygon.IsEmpty()) { - return true; - } - return aTraits.AddVerticesTo(mPass, aInfo, itemIndex, &polygon); - } - return aTraits.AddVerticesTo(mPass, aInfo, itemIndex); - } - return aTraits.AddInstanceTo(mPass, aInfo); - } - - bool Fail() { - MOZ_ASSERT(!mStatus.isSome() || !mStatus.value()); - mStatus = Some(false); - return false; - } - - bool Commit() { - MOZ_ASSERT(!mStatus.isSome() || !mStatus.value()); - if (mStatus.isSome()) { - return false; - } - mStatus = Some(true); - return true; - } - - ~Txn() { - if (!mStatus.isSome() || !mStatus.value()) { - mPass->mVertices.RestorePosition(mPrevVertexPos); - mPass->mInstances.RestorePosition(mPrevInstancePos); - mPass->mItems.RestorePosition(mPrevItemPos); - } - } - - private: - BatchRenderPass* mPass; - VertexStagingBuffer::Position mPrevVertexPos; - VertexStagingBuffer::Position mPrevItemPos; - ConstantStagingBuffer::Position mPrevInstancePos; - Maybe mStatus; - }; -}; - -// Shaders which sample from a texture should inherit from this. -class TexturedRenderPass : public BatchRenderPass -{ -public: - explicit TexturedRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem); - -protected: - // Add a set of draw rects based on a visible region. The texture size and - // scaling factor are used to compute uv-coordinates. - // - // The origin is the offset from the draw rect to the layer bounds. You can - // also think of it as the translation from layer space into texture space, - // pre-scaling. For example, ImageLayers use the texture bounds as their - // draw rect, so the origin will be (0, 0). ContainerLayer intermediate - // surfaces, on the other hand, are relative to the target offset of the - // layer. In all cases the visible region may be partially occluded, so - // knowing the true origin is important. - bool AddItems(Txn& aTxn, - const ItemInfo& aInfo, - const nsIntRegion& aDrawRects, - const gfx::IntPoint& aDestOrigin, - const gfx::IntSize& aTextureSize, - const Maybe& aScale = Nothing()) - { - gfx::Point origin(aDestOrigin); - for (auto iter = aDrawRects.RectIter(); !iter.Done(); iter.Next()) { - gfx::Rect drawRect = gfx::Rect(iter.Get()); - if (!AddItem(aTxn, aInfo, drawRect, origin, aTextureSize, aScale)) { - return false; - } - } - return true; - } - -private: - // Add a draw instance to the given destination rect. Texture coordinates - // are built from the given texture size, optional scaling factor, and - // texture origin relative to the draw rect. This will ultimately call - // AddClippedItem, potentially clipping the draw rect if needed. - bool AddItem(Txn& aTxn, - const ItemInfo& aInfo, - const gfx::Rect& aDrawRect, - const gfx::Point& aDestOrigin, - const gfx::IntSize& aTextureSize, - const Maybe& aTextureScale = Nothing()); - - // Add an item that has gone through any necessary clipping already. This - // is the final destination for handling textured items. - bool AddClippedItem(Txn& aTxn, - const ItemInfo& aInfo, - const gfx::Rect& aDrawRect, - const gfx::Point& aDestOrigin, - const gfx::IntSize& aTextureSize, - const Maybe& aScale); - -protected: - TextureFlags mTextureFlags; -}; - -// This is only available when MLGDevice::CanUseClearView returns true. -class ClearViewPass final : public RenderPassMLGPU -{ -public: - ClearViewPass(FrameBuilder* aBuilder, const ItemInfo& aItem); - - bool IsCompatible(const ItemInfo& aItem) override; - void ExecuteRendering() override; - - RenderPassType GetType() const override { - return RenderPassType::ClearView; - } - -private: - bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override; - -private: - // Note: Not a RefPtr since this would create a cycle. - RenderViewMLGPU* mView; - gfx::Color mColor; - nsTArray mRects; -}; - -// SolidColorPass is used when ClearViewPass is not available, or when -// the layer has masks, or subpixel or complex transforms. -class SolidColorPass final : public BatchRenderPass -{ -public: - explicit SolidColorPass(FrameBuilder* aBuilder, const ItemInfo& aItem); - - RenderPassType GetType() const override { - return RenderPassType::SolidColor; - } - -private: - bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override; - void SetupPipeline() override; - float GetOpacity() const override; -}; - -class SingleTexturePass final : public TexturedRenderPass -{ -public: - explicit SingleTexturePass(FrameBuilder* aBuilder, const ItemInfo& aItem); - - RenderPassType GetType() const override { - return RenderPassType::SingleTexture; - } - -private: - bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override; - void SetupPipeline() override; - float GetOpacity() const override { - return mOpacity; - } - Maybe GetBlendState() const override; - -private: - RefPtr mTexture; - gfx::SamplingFilter mFilter; - float mOpacity; -}; - -class ComponentAlphaPass final : public TexturedRenderPass -{ -public: - explicit ComponentAlphaPass(FrameBuilder* aBuilder, const ItemInfo& aItem); - - RenderPassType GetType() const override { - return RenderPassType::ComponentAlpha; - } - -private: - bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override; - void SetupPipeline() override; - float GetOpacity() const override; - Maybe GetBlendState() const override { - return Some(MLGBlendState::ComponentAlpha); - } - -private: - PaintedLayerMLGPU* mAssignedLayer; - RefPtr mTextureOnBlack; - RefPtr mTextureOnWhite; -}; - -class VideoRenderPass final : public TexturedRenderPass -{ -public: - explicit VideoRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem); - - RenderPassType GetType() const override { - return RenderPassType::Video; - } - -private: - bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override; - void SetupPipeline() override; - float GetOpacity() const override { - return mOpacity; - } - -private: - RefPtr mHost; - RefPtr mTexture; - gfx::SamplingFilter mFilter; - float mOpacity; -}; - -class RenderViewPass final : public TexturedRenderPass -{ -public: - RenderViewPass(FrameBuilder* aBuilder, const ItemInfo& aItem); - - RenderPassType GetType() const override { - return RenderPassType::RenderView; - } - -private: - bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override; - void SetupPipeline() override; - bool OnPrepareBuffers() override; - float GetOpacity() const override; - bool PrepareBlendState(); - -private: - ConstantBufferSection mBlendConstants; - ContainerLayerMLGPU* mAssignedLayer; - RefPtr mSource; - // Note: we don't use RefPtr here since that would cause a cycle. RenderViews - // and RenderPasses are both scoped to the frame anyway. - RenderViewMLGPU* mParentView; - gfx::IntRect mBackdropCopyRect; - Maybe mBlendMode; -}; - -} // namespace layers -} // namespace mozilla - -#endif diff --git a/gfx/layers/mlgpu/RenderViewMLGPU.cpp b/gfx/layers/mlgpu/RenderViewMLGPU.cpp deleted file mode 100644 index edec15cf2d6b..000000000000 --- a/gfx/layers/mlgpu/RenderViewMLGPU.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "RenderViewMLGPU.h" -#include "ContainerLayerMLGPU.h" -#include "FrameBuilder.h" -#include "gfxPrefs.h" -#include "LayersHelpers.h" -#include "LayersLogging.h" -#include "MLGDevice.h" -#include "RenderPassMLGPU.h" -#include "ShaderDefinitionsMLGPU.h" -#include "UtilityMLGPU.h" - -namespace mozilla { -namespace layers { - -using namespace gfx; - -RenderViewMLGPU::RenderViewMLGPU(FrameBuilder* aBuilder, - MLGRenderTarget* aTarget, - const nsIntRegion& aInvalidRegion) - : RenderViewMLGPU(aBuilder, nullptr) -{ - mTarget = aTarget; - mInvalidBounds = aInvalidRegion.GetBounds(); - - AL_LOG("RenderView %p root with invalid area %s\n", - this, - Stringify(mInvalidBounds).c_str()); -} - -RenderViewMLGPU::RenderViewMLGPU(FrameBuilder* aBuilder, - ContainerLayerMLGPU* aContainer, - RenderViewMLGPU* aParent) - : RenderViewMLGPU(aBuilder, aParent) -{ - mContainer = aContainer; - mTargetOffset = aContainer->GetTargetOffset(); - mInvalidBounds = aContainer->GetInvalidRect(); - mActualBounds = Some(IntRect()); - MOZ_ASSERT(!mInvalidBounds.IsEmpty()); - - AL_LOG("RenderView %p starting with container %p and invalid area %s\n", - this, - aContainer->GetLayer(), - Stringify(mInvalidBounds).c_str()); -} - -RenderViewMLGPU::RenderViewMLGPU(FrameBuilder* aBuilder, RenderViewMLGPU* aParent) - : mBuilder(aBuilder), - mDevice(aBuilder->GetDevice()), - mParent(aParent), - mContainer(nullptr), - mFinishedBuilding(false), - mCurrentLayerBufferIndex(kInvalidResourceIndex), - mCurrentMaskRectBufferIndex(kInvalidResourceIndex), - mNextSortIndex(1), - mUseDepthBuffer(gfxPrefs::AdvancedLayersEnableDepthBuffer()), - mDepthBufferNeedsClear(false) -{ - if (aParent) { - aParent->AddChild(this); - } -} - -RenderViewMLGPU::~RenderViewMLGPU() -{ - for (const auto& child : mChildren) { - child->mParent = nullptr; - } -} - -IntSize -RenderViewMLGPU::GetSize() const -{ - MOZ_ASSERT(mFinishedBuilding); - return mTarget->GetSize(); -} - -MLGRenderTarget* -RenderViewMLGPU::GetRenderTarget() const -{ - MOZ_ASSERT(mFinishedBuilding); - return mTarget; -} - -void -RenderViewMLGPU::AddChild(RenderViewMLGPU* aParent) -{ - mChildren.push_back(aParent); -} - -void -RenderViewMLGPU::Render() -{ - // We render tiles front-to-back, depth-first, to minimize render target switching. - for (const auto& child : mChildren) { - child->Render(); - } - - ExecuteRendering(); -} - -void -RenderViewMLGPU::FinishBuilding() -{ - MOZ_ASSERT(!mFinishedBuilding); - mFinishedBuilding = true; - - if (mContainer) { - MOZ_ASSERT(!mTarget); - - MLGRenderTargetFlags flags = MLGRenderTargetFlags::Default; - if (mUseDepthBuffer) { - flags |= MLGRenderTargetFlags::ZBuffer; - } - mTarget = mContainer->UpdateRenderTarget(mDevice, flags); - } -} - -void -RenderViewMLGPU::AddItem(LayerMLGPU* aItem, - const IntRect& aRect, - Maybe&& aGeometry) -{ - AL_LOG("RenderView %p analyzing layer %p\n", this, aItem->GetLayer()); - - // If the item is not visible at all, skip it. - if (aItem->GetComputedOpacity() == 0.0f) { - AL_LOG("RenderView %p culling item %p with no opacity\n", - this, - aItem->GetLayer()); - return; - } - - // When using the depth buffer, the z-index for items is important. - // - // Sort order starts at 1 and goes to positive infinity, with smaller values - // being closer to the screen. Our viewport is the same, with anything - // outside of [0.0, 1.0] being culled, and lower values occluding higher - // values. To make this work our projection transform scales the z-axis. - // Note that we do not use 0 as a sorting index (when depth-testing is - // enabled) because this would result in a z-value of 1.0, which would be - // culled. - ItemInfo info(mBuilder, this, aItem, mNextSortIndex++, aRect, Move(aGeometry)); - - // If the item is not visible, or we can't add it to the layer constant - // buffer for some reason, bail out. - if (!UpdateVisibleRegion(info) || !mBuilder->AddLayerToConstantBuffer(info)) { - AL_LOG("RenderView %p culled item %p!\n", this, aItem->GetLayer()); - return; - } - - // We support all layer types now. - MOZ_ASSERT(info.type != RenderPassType::Unknown); - - if (info.renderOrder == RenderOrder::FrontToBack) { - AddItemFrontToBack(aItem, info); - } else { - AddItemBackToFront(aItem, info); - } -} - -bool -RenderViewMLGPU::UpdateVisibleRegion(ItemInfo& aItem) -{ - // If the item has some kind of complex transform, we perform a very - // simple occlusion test and move on. We using a depth buffer we skip - // CPU-based occlusion culling as well, since the GPU will do most of our - // culling work for us. - if (mUseDepthBuffer || - !aItem.translation || - !gfxPrefs::AdvancedLayersEnableCPUOcclusion()) - { - // Update the render region even if we won't compute visibility, since some - // layer types (like Canvas and Image) need to have the visible region - // clamped. - LayerIntRegion region = Move(aItem.layer->GetShadowVisibleRegion()); - aItem.layer->SetRegionToRender(Move(region)); - - AL_LOG("RenderView %p simple occlusion test, bounds=%s, translation?=%d\n", - this, - Stringify(aItem.bounds).c_str(), - aItem.translation ? 1 : 0); - return mInvalidBounds.Intersects(aItem.bounds); - } - - MOZ_ASSERT(aItem.rectilinear); - - AL_LOG("RenderView %p starting visibility tests:\n", this); - AL_LOG(" occluded=%s\n", Stringify(mOccludedRegion).c_str()); - - // Compute the translation into render target space. - LayerIntPoint translation = - LayerIntPoint::FromUnknownPoint(aItem.translation.value() - mTargetOffset); - AL_LOG(" translation=%s\n", Stringify(translation).c_str()); - - IntRect clip = aItem.layer->GetComputedClipRect().ToUnknownRect(); - AL_LOG(" clip=%s\n", Stringify(translation).c_str()); - - LayerIntRegion region = Move(aItem.layer->GetShadowVisibleRegion()); - region.MoveBy(translation); - AL_LOG(" effective-visible=%s\n", Stringify(region).c_str()); - - region.SubOut(mOccludedRegion); - region.AndWith(LayerIntRect::FromUnknownRect(mInvalidBounds)); - region.AndWith(LayerIntRect::FromUnknownRect(clip)); - if (region.IsEmpty()) { - return false; - } - - // Move the visible region back into layer space. - region.MoveBy(-translation); - AL_LOG(" new-local-visible=%s\n", Stringify(region).c_str()); - - aItem.layer->SetRegionToRender(Move(region)); - - // Apply the new occluded area. We do another dance with the translation to - // avoid copying the region. We do this after the SetRegionToRender call to - // accomodate the possiblity of a layer changing its visible region. - if (aItem.opaque) { - mOccludedRegion.MoveBy(-translation); - mOccludedRegion.OrWith(aItem.layer->GetShadowVisibleRegion()); - mOccludedRegion.MoveBy(translation); - AL_LOG(" new-occluded=%s\n", Stringify(mOccludedRegion).c_str()); - - // If the occluded region gets too complicated, we reset it. - if (mOccludedRegion.GetNumRects() >= 32) { - mOccludedRegion.SetEmpty(); - AL_LOG(" clear-occluded, too many rects\n"); - } - } - return true; -} - -void -RenderViewMLGPU::AddItemFrontToBack(LayerMLGPU* aLayer, ItemInfo& aItem) -{ - // We receive items in front-to-back order. Ideally we want to push items - // as far back into batches impossible, to ensure the GPU can do a good - // job at culling. However we also want to make sure we actually batch - // items versus drawing one primitive per pass. - // - // As a compromise we look at the most 3 recent batches and then give up. - // This can be tweaked in the future. - static const size_t kMaxSearch = 3; - size_t iterations = 0; - for (auto iter = mFrontToBack.rbegin(); iter != mFrontToBack.rend(); iter++) { - RenderPassMLGPU* pass = (*iter); - if (pass->IsCompatible(aItem) && pass->AcceptItem(aItem)) { - AL_LOG("RenderView %p added layer %p to pass %p (%d)\n", - this, aLayer->GetLayer(), pass, int(pass->GetType())); - return; - } - if (++iterations > kMaxSearch) { - break; - } - } - - RefPtr pass = RenderPassMLGPU::CreatePass(mBuilder, aItem); - if (!pass || !pass->AcceptItem(aItem)) { - MOZ_ASSERT_UNREACHABLE("Could not build a pass for item!"); - return; - } - AL_LOG("RenderView %p added layer %p to new pass %p (%d)\n", - this, aLayer->GetLayer(), pass.get(), int(pass->GetType())); - - mFrontToBack.push_back(pass); -} - -void -RenderViewMLGPU::AddItemBackToFront(LayerMLGPU* aLayer, ItemInfo& aItem) -{ - // We receive layers in front-to-back order, but there are two cases when we - // actually draw back-to-front: when the depth buffer is disabled, or when - // using the depth buffer and the item has transparent pixels (and therefore - // requires blending). In these cases we will build vertex and constant - // buffers in reverse, as well as execute batches in reverse, to ensure the - // correct ordering. - // - // Note: We limit the number of batches we search through, since it's better - // to add new draw calls than spend too much time finding compatible - // batches further down. - static const size_t kMaxSearch = 10; - size_t iterations = 0; - for (auto iter = mBackToFront.begin(); iter != mBackToFront.end(); iter++) { - RenderPassMLGPU* pass = (*iter); - if (pass->IsCompatible(aItem) && pass->AcceptItem(aItem)) { - AL_LOG("RenderView %p added layer %p to pass %p (%d)\n", - this, aLayer->GetLayer(), pass, int(pass->GetType())); - return; - } - if (pass->Intersects(aItem)) { - break; - } - if (++iterations > kMaxSearch) { - break; - } - } - - RefPtr pass = RenderPassMLGPU::CreatePass(mBuilder, aItem); - if (!pass || !pass->AcceptItem(aItem)) { - MOZ_ASSERT_UNREACHABLE("Could not build a pass for item!"); - return; - } - AL_LOG("RenderView %p added layer %p to new pass %p (%d)\n", - this, aLayer->GetLayer(), pass.get(), int(pass->GetType())); - - mBackToFront.push_front(pass); -} - -void -RenderViewMLGPU::Prepare() -{ - if (!mTarget) { - return; - } - - // Prepare front-to-back passes. These are only present when using the depth - // buffer, and they contain only opaque data. - for (RefPtr& pass : mFrontToBack) { - pass->PrepareForRendering(); - } - - // Prepare the Clear buffer, which will fill the render target with transparent - // pixels. This must happen before we set up world constants, since it can - // create new z-indices. - PrepareClear(); - - // Prepare the world constant buffer. This must be called after we've - // finished allocating all z-indices. - { - WorldConstants vsConstants; - Matrix4x4 projection = Matrix4x4::Translation(-1.0, 1.0, 0.0); - projection.PreScale(2.0 / float(mTarget->GetSize().width), - 2.0 / float(mTarget->GetSize().height), - 1.0f); - projection.PreScale(1.0f, -1.0f, 1.0f); - - memcpy(vsConstants.projection, &projection._11, 64); - vsConstants.targetOffset = Point(mTargetOffset); - vsConstants.sortIndexOffset = PrepareDepthBuffer(); - - SharedConstantBuffer* shared = mDevice->GetSharedVSBuffer(); - if (!shared->Allocate(&mWorldConstants, vsConstants)) { - return; - } - } - - // Prepare back-to-front passes. In depth buffer mode, these contain draw - // calls that might produce transparent pixels. When using CPU-based occlusion - // culling, all draw calls are back-to-front. - for (RefPtr& pass : mBackToFront) { - pass->PrepareForRendering(); - } - - // Now, process children. - for (const auto& iter : mChildren) { - iter->Prepare(); - } -} - -void -RenderViewMLGPU::ExecuteRendering() -{ - if (!mTarget) { - return; - } - - mDevice->SetRenderTarget(mTarget); - mDevice->SetViewport(IntRect(IntPoint(0, 0), mTarget->GetSize())); - mDevice->SetScissorRect(Some(mInvalidBounds)); - - if (!mWorldConstants.IsValid()) { - gfxWarning() << "Failed to allocate constant buffer for world transform"; - return; - } - mDevice->SetVSConstantBuffer(kWorldConstantBufferSlot, &mWorldConstants); - - // If using the depth buffer, clear it (if needed) and enable writes. - if (mUseDepthBuffer) { - if (mDepthBufferNeedsClear) { - mDevice->ClearDepthBuffer(mTarget); - } - mDevice->SetDepthTestMode(MLGDepthTestMode::Write); - } - - // Opaque items, rendered front-to-back. - for (auto iter = mFrontToBack.begin(); iter != mFrontToBack.end(); iter++) { - ExecutePass(*iter); - } - - if (mUseDepthBuffer) { - // From now on we might be rendering transparent pixels, so we disable - // writing to the z-buffer. - mDevice->SetDepthTestMode(MLGDepthTestMode::ReadOnly); - } - - // Clear any pixels that are not occluded, and therefore might require - // blending. - DrawClear(); - - // Render back-to-front passes. - for (auto iter = mBackToFront.begin(); iter != mBackToFront.end(); iter++) { - ExecutePass(*iter); - } - - // We repaint the entire invalid region, even if it is partially occluded. - // Thus it's safe for us to clear the invalid area here. If we ever switch - // to nsIntRegions, we will have to take the difference between the paitned - // area and the invalid area. - if (mContainer) { - mContainer->ClearInvalidRect(); - } -} - -void -RenderViewMLGPU::ExecutePass(RenderPassMLGPU* aPass) -{ - if (!aPass->IsPrepared()) { - return; - } - - // Change the layer buffer if needed. - if (aPass->GetLayerBufferIndex() != mCurrentLayerBufferIndex) { - mCurrentLayerBufferIndex = aPass->GetLayerBufferIndex(); - - ConstantBufferSection section = mBuilder->GetLayerBufferByIndex(mCurrentLayerBufferIndex); - mDevice->SetVSConstantBuffer(kLayerBufferSlot, §ion); - } - - // Change the mask rect buffer if needed. - if (aPass->GetMaskRectBufferIndex() && - aPass->GetMaskRectBufferIndex().value() != mCurrentMaskRectBufferIndex) - { - mCurrentMaskRectBufferIndex = aPass->GetMaskRectBufferIndex().value(); - - ConstantBufferSection section = mBuilder->GetMaskRectBufferByIndex(mCurrentMaskRectBufferIndex); - mDevice->SetVSConstantBuffer(kMaskBufferSlot, §ion); - } - - // Change the blend state if needed. - if (Maybe blendState = aPass->GetBlendState()) { - mDevice->SetBlendState(blendState.value()); - } - - aPass->ExecuteRendering(); -} - -int32_t -RenderViewMLGPU::PrepareDepthBuffer() -{ - if (!mUseDepthBuffer) { - return 0; - } - - // Rather than clear the depth buffer every frame, we offset z-indices each - // frame, starting with indices far away from the screen and moving toward - // the user each successive frame. This ensures that frames can re-use the - // depth buffer but never collide with previously written values. - // - // Once a frame runs out of sort indices, we finally clear the depth buffer - // and start over again. - - // Note: the lowest sort index (kDepthLimit) is always occluded since it will - // resolve to the clear value - kDepthLimit / kDepthLimit == 1.0. - // - // If we don't have any more indices to allocate, we need to clear the depth - // buffer and start fresh. - int32_t highestIndex = mTarget->GetLastDepthStart(); - if (highestIndex < mNextSortIndex) { - mDepthBufferNeedsClear = true; - highestIndex = kDepthLimit; - } - - // We should not have more than kDepthLimit layers to draw. The last known - // sort index might appear in the depth buffer and occlude something, so - // we subtract 1. This ensures all our indices will compare less than all - // old indices. - int32_t sortOffset = highestIndex - mNextSortIndex - 1; - MOZ_ASSERT(sortOffset >= 0); - - mTarget->SetLastDepthStart(sortOffset); - return sortOffset; -} - -void -RenderViewMLGPU::PrepareClear() -{ - // Get the list of rects to clear. If using the depth buffer, we don't - // care if it's accurate since the GPU will do occlusion testing for us. - // If not using the depth buffer, we subtract out the occluded region. - LayerIntRegion region = LayerIntRect::FromUnknownRect(mInvalidBounds); - if (!mUseDepthBuffer) { - // Don't let the clear region become too complicated. - region.SubOut(mOccludedRegion); - region.SimplifyOutward(kMaxClearViewRects); - } - for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) { - mClearRects.AppendElement(iter.Get().ToUnknownRect()); - } - - // If ClearView is supported and we're not using a depth buffer, we - // can stop here. We'll use the rects as inputs to ClearView. - if (mClearRects.IsEmpty() || (mDevice->CanUseClearView() && !mUseDepthBuffer)) { - return; - } - - // Set up vertices for a shader-based clear. - mDevice->GetSharedVertexBuffer()->Allocate( - &mClearInput, - mClearRects.Length(), - sizeof(IntRect), - mClearRects.Elements()); - mClearRects.Clear(); - - // Note that we use the lowest available sorting index, to ensure that when - // using the z-buffer, we don't draw over already-drawn content. - ClearConstants consts(mNextSortIndex++); - mDevice->GetSharedVSBuffer()->Allocate(&mClearConstants, consts); -} - -void -RenderViewMLGPU::DrawClear() -{ - // If we've set up vertices for a shader-based clear, execute that now. - if (mClearInput.IsValid()) { - mDevice->SetTopology(MLGPrimitiveTopology::UnitQuad); - mDevice->SetVertexShader(VertexShaderID::Clear); - mDevice->SetVertexBuffer(1, &mClearInput); - mDevice->SetVSConstantBuffer(kClearConstantBufferSlot, &mClearConstants); - mDevice->SetBlendState(MLGBlendState::Copy); - mDevice->SetPixelShader(PixelShaderID::Clear); - mDevice->DrawInstanced(4, mClearInput.NumVertices(), 0, 0); - return; - } - - // Otherwise, if we have a normal rect list, we wanted to use the faster - // ClearView. - if (!mClearRects.IsEmpty()) { - Color color(0.0, 0.0, 0.0, 0.0); - mDevice->ClearView(mTarget, color, mClearRects.Elements(), mClearRects.Length()); - } -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/RenderViewMLGPU.h b/gfx/layers/mlgpu/RenderViewMLGPU.h deleted file mode 100644 index d5d3130fb04c..000000000000 --- a/gfx/layers/mlgpu/RenderViewMLGPU.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_RenderViewMLGPU_h -#define mozilla_gfx_layers_mlgpu_RenderViewMLGPU_h - -#include "LayerManagerMLGPU.h" -#include "RenderPassMLGPU.h" -#include "Units.h" -#include - -namespace mozilla { -namespace layers { - -class FrameBuilder; -class ContainerLayerMLGPU; -class MLGRenderTarget; - -class RenderViewMLGPU -{ -public: - NS_INLINE_DECL_REFCOUNTING(RenderViewMLGPU) - - // Constructor for the widget render target. - RenderViewMLGPU(FrameBuilder* aBuilder, - MLGRenderTarget* aTarget, - const nsIntRegion& aInvalidRegion); - - // Constructor for intermediate surfaces. - RenderViewMLGPU(FrameBuilder* aBuilder, - ContainerLayerMLGPU* aContainer, - RenderViewMLGPU* aParent); - - void Prepare(); - void Render(); - void AddChild(RenderViewMLGPU* aParent); - void AddItem(LayerMLGPU* aItem, - const gfx::IntRect& aBounds, - Maybe&& aGeometry); - void FinishBuilding(); - - const gfx::IntPoint& GetTargetOffset() const { - return mTargetOffset; - } - RenderViewMLGPU* GetParent() const { - return mParent; - } - bool HasDepthBuffer() const { - return mUseDepthBuffer; - } - - // The size and render target cannot be read until the view has finished - // building, since we try to right-size the render target to the visible - // region. - MLGRenderTarget* GetRenderTarget() const; - gfx::IntSize GetSize() const; - - gfx::IntRect GetInvalidRect() const { - return mInvalidBounds; - } - -private: - RenderViewMLGPU(FrameBuilder* aBuilder, RenderViewMLGPU* aParent); - ~RenderViewMLGPU(); - - void ExecuteRendering(); - bool UpdateVisibleRegion(ItemInfo& aItem); - void AddItemFrontToBack(LayerMLGPU* aLayer, ItemInfo& aItem); - void AddItemBackToFront(LayerMLGPU* aLayer, ItemInfo& aItem); - - void PrepareClear(); - void DrawClear(); - - void ExecutePass(RenderPassMLGPU* aPass); - - // Return the sorting index offset to use. - int32_t PrepareDepthBuffer(); - -private: - std::deque> mFrontToBack; - std::deque> mBackToFront; - - FrameBuilder* mBuilder; - RefPtr mDevice; - RenderViewMLGPU* mParent; - std::vector> mChildren; - - // Shader data. - ConstantBufferSection mWorldConstants; - - // If using ClearView-based clears. - nsTArray mClearRects; - - // If using shader-based clears. - VertexBufferSection mClearInput; - ConstantBufferSection mClearConstants; - - // Either an MLGSwapChain-derived render target, or an intermediate surface. - RefPtr mTarget; - - // For intermediate render targets only, this is the layer owning the render target. - ContainerLayerMLGPU* mContainer; - - // The offset adjustment from container layer space to render target space. - // This is 0,0 for the root view. - gfx::IntPoint mTargetOffset; - - // The invalid bounds as computed by LayerTreeInvalidation. This is the initial - // render bounds size, if invalidation is disabled. - gfx::IntRect mInvalidBounds; - - // The actual bounds of the view as computed by summing the visible bounds of - // child layers. We use this to right-size the intermediate surface. If unset, - // we do not right-size the intermediate surface. - Maybe mActualBounds; - - // The occluded region, which is updated every time we process an opaque, - // rectangular item. This is not actually in LayerPixels, we do this to - // avoid FromUnknownRegion which has array copies. - LayerIntRegion mOccludedRegion; - - // True if we've finished adding layers to the view. - bool mFinishedBuilding; - - // This state is used to avoid changing buffers while we execute batches. - size_t mCurrentLayerBufferIndex; - size_t mCurrentMaskRectBufferIndex; - - // Depth-buffer tracking. - int32_t mNextSortIndex; - bool mUseDepthBuffer; - bool mDepthBufferNeedsClear; -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_RenderViewMLGPU_h diff --git a/gfx/layers/mlgpu/ShaderDefinitionsMLGPU-inl.h b/gfx/layers/mlgpu/ShaderDefinitionsMLGPU-inl.h deleted file mode 100644 index 03890f1aa115..000000000000 --- a/gfx/layers/mlgpu/ShaderDefinitionsMLGPU-inl.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _include_gfx_layers_mlgpu_ShaderDefinitions_inl_h -#define _include_gfx_layers_mlgpu_ShaderDefinitions_inl_h - -namespace mozilla { -namespace layers { -namespace mlg { - -// This is a helper class for writing vertices for unit-quad based -// shaders, since they all share the same input layout. -struct SimpleVertex -{ - SimpleVertex(const gfx::Rect& aRect, - uint32_t aLayerIndex, - int aDepth) - : rect(aRect), - layerIndex(aLayerIndex), - depth(aDepth) - {} - - gfx::Rect rect; - uint32_t layerIndex; - int depth; -}; - -bool -SimpleTraits::AddInstanceTo(ShaderRenderPass* aPass, const ItemInfo& aItem) const -{ - return aPass->GetInstances()->AddItem(SimpleVertex( - mRect, aItem.layerIndex, aItem.sortOrder)); -} - - -inline bool -ColorTraits::AddItemTo(ShaderRenderPass* aPass) const -{ - return aPass->GetItems()->AddItem(mColor); -} - -inline bool -TexturedTraits::AddItemTo(ShaderRenderPass* aPass) const -{ - return aPass->GetItems()->AddItem(mTexCoords); -} - -} // namespace mlg -} // namespace layers -} // namespace mozilla - -#endif // _include_gfx_layers_mlgpu_ShaderDefinitions_inl_h diff --git a/gfx/layers/mlgpu/ShaderDefinitionsMLGPU.cpp b/gfx/layers/mlgpu/ShaderDefinitionsMLGPU.cpp deleted file mode 100644 index 2c916e8411a8..000000000000 --- a/gfx/layers/mlgpu/ShaderDefinitionsMLGPU.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ShaderDefinitionsMLGPU.h" -#include "RenderPassMLGPU.h" - -namespace mozilla { -namespace layers { -namespace mlg { - -using namespace gfx; - -// Helper function for adding triangle vertices to shader buffers. -struct TriangleVertex -{ - TriangleVertex(const gfx::Point& aPoint, - const ItemInfo& aItem, - uint32_t aItemIndex) - : point(aPoint), - layerIndex(aItem.layerIndex), - depth(aItem.sortOrder), - itemIndex(aItemIndex) - {} - - gfx::Point point; - uint32_t layerIndex; - int depth; - uint32_t itemIndex; -}; - -bool -SimpleTraits::AddVerticesTo(ShaderRenderPass* aPass, - const ItemInfo& aItem, - uint32_t aItemIndex, - const gfx::Polygon* aGeometry) const -{ - VertexStagingBuffer* vertices = aPass->GetVertices(); - - // If we don't have geometry, take a fast path where we can hardcode - // the set of triangles. - if (!aGeometry) { - if (!vertices->PrependItem(TriangleVertex(mRect.BottomLeft(), aItem, aItemIndex)) || - !vertices->PrependItem(TriangleVertex(mRect.TopLeft(), aItem, aItemIndex)) || - !vertices->PrependItem(TriangleVertex(mRect.TopRight(), aItem, aItemIndex)) || - !vertices->PrependItem(TriangleVertex(mRect.TopRight(), aItem, aItemIndex)) || - !vertices->PrependItem(TriangleVertex(mRect.BottomRight(), aItem, aItemIndex)) || - !vertices->PrependItem(TriangleVertex(mRect.BottomLeft(), aItem, aItemIndex))) - { - return false; - } - return true; - } - - // Slow path: full-fledged geometry. - nsTArray triangles = aGeometry->ToTriangles(); - for (const Triangle& t : triangles) { - if (!vertices->PrependItem(TriangleVertex(t.p1, aItem, aItemIndex)) || - !vertices->PrependItem(TriangleVertex(t.p2, aItem, aItemIndex)) || - !vertices->PrependItem(TriangleVertex(t.p3, aItem, aItemIndex))) - { - return false; - } - } - return true; -} - -struct TexturedTriangleVertex -{ - TexturedTriangleVertex(const gfx::Point& aPoint, - const gfx::Point& aTexCoord, - const ItemInfo& aItem) - : point(aPoint), - texCoord(aTexCoord), - layerIndex(aItem.layerIndex), - depth(aItem.sortOrder) - {} - - gfx::Point point; - gfx::Point texCoord; - uint32_t layerIndex; - int depth; -}; - -bool -TexturedTraits::AddVerticesTo(ShaderRenderPass* aPass, - const ItemInfo& aItem, - uint32_t aItemIndex, - const gfx::Polygon* aGeometry) const -{ - VertexStagingBuffer* vertices = aPass->GetVertices(); - - using Vertex = TexturedTriangleVertex; - - // If we don't have geometry, take a fast path where we can hardcode - // the set of triangles. - if (!aGeometry) { - if (!vertices->PrependItem(Vertex(mRect.BottomLeft(), mTexCoords.BottomLeft(), aItem)) || - !vertices->PrependItem(Vertex(mRect.TopLeft(), mTexCoords.TopLeft(), aItem)) || - !vertices->PrependItem(Vertex(mRect.TopRight(), mTexCoords.TopRight(), aItem)) || - !vertices->PrependItem(Vertex(mRect.TopRight(), mTexCoords.TopRight(), aItem)) || - !vertices->PrependItem(Vertex(mRect.BottomRight(), mTexCoords.BottomRight(), aItem)) || - !vertices->PrependItem(Vertex(mRect.BottomLeft(), mTexCoords.BottomLeft(), aItem))) - { - return false; - } - return true; - } - - // Slow path: full-fledged geometry. - nsTArray triangles = - GenerateTexturedTriangles(*aGeometry, mRect, mTexCoords); - for (const TexturedTriangle& t: triangles) { - if (!vertices->PrependItem(Vertex(t.p1, t.textureCoords.p1, aItem)) || - !vertices->PrependItem(Vertex(t.p2, t.textureCoords.p2, aItem)) || - !vertices->PrependItem(Vertex(t.p3, t.textureCoords.p3, aItem))) - { - return false; - } - } - return true; -} - -} // namespace mlg -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/ShaderDefinitionsMLGPU.h b/gfx/layers/mlgpu/ShaderDefinitionsMLGPU.h deleted file mode 100644 index 44ba95335a4c..000000000000 --- a/gfx/layers/mlgpu/ShaderDefinitionsMLGPU.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MOZILLA_GFX_SHADERDEFINITIONSMLGPU_H -#define MOZILLA_GFX_SHADERDEFINITIONSMLGPU_H - -#include "mozilla/gfx/Point.h" -#include "mozilla/gfx/Triangle.h" -#include "mozilla/gfx/Types.h" -#include "mozilla/layers/LayersHelpers.h" -#include "nsTArray.h" - -namespace mozilla { -namespace layers { - -struct ItemInfo; -class ShaderRenderPass; - -namespace mlg { - -// These may need to move into run-time values determined by MLGDevice. -static const size_t kConstantBufferElementSize = 16; -static const size_t kMaxConstantBufferSize = 4096 * kConstantBufferElementSize; - -// Vertex shader slots. We reverse the first two slots across all shaders, -// and the first three slots free across all RenderPass shaders, for -// uniformity. -static const uint32_t kWorldConstantBufferSlot = 0; -static const uint32_t kLayerBufferSlot = 1; -static const uint32_t kItemBufferSlot = 2; -static const uint32_t kMaskBufferSlot = 3; -static const uint32_t kBlendConstantBufferSlot = 4; -static const uint32_t kClearConstantBufferSlot = 2; - -// This is specified in common-ps.hlsl. -static const uint32_t kMaskLayerTextureSlot = 4; -static const uint32_t kDefaultSamplerSlot = 0; -static const uint32_t kMaskSamplerSlot = 1; - -// These are the maximum slot numbers we bind. We assert that no binding -// happens above the max slot, since we try to clear buffer bindings at -// the end of each frame. -static const uint32_t kMaxVertexShaderConstantBuffers = 5; -static const uint32_t kMaxPixelShaderConstantBuffers = 2; - -// Maximum depth in the depth buffer. This must match common-vs.hlsl. -static const int32_t kDepthLimit = 1000000; - -struct WorldConstants -{ - float projection[4][4]; - gfx::Point targetOffset; - int sortIndexOffset; - float padding; -}; - -struct ClearConstants -{ - explicit ClearConstants(int aDepth) : depth(aDepth) - {} - int depth; - int padding[3]; -}; - -struct LayerConstants -{ - float transform[4][4]; - gfx::Rect clipRect; - uint32_t maskIndex; - uint32_t padding[3]; -}; - -struct MaskCombineInput -{ - float texCoords[4]; -}; - -struct MaskInformation -{ - MaskInformation(float aOpacity, bool aHasMask) - : opacity(aOpacity), - hasMask(aHasMask ? 1 : 0) - {} - float opacity; - uint32_t hasMask; - uint32_t padding[2]; -}; - -struct YCbCrShaderConstants { - float yuvColorMatrix[3][4]; -}; - -struct BlendVertexShaderConstants { - float backdropTransform[4][4]; -}; - -struct SimpleTraits -{ - explicit SimpleTraits(const gfx::Rect& aRect) - : mRect(aRect) - {} - - bool AddInstanceTo(ShaderRenderPass* aPass, const ItemInfo& aItem) const; - bool AddVerticesTo(ShaderRenderPass* aPass, - const ItemInfo& aItem, - uint32_t aItemIndex, - const gfx::Polygon* aGeometry = nullptr) const; - - gfx::Rect mRect; -}; - -struct ColorTraits : public SimpleTraits -{ - ColorTraits(const gfx::Rect& aRect, const gfx::Color& aColor) - : SimpleTraits(aRect), mColor(aColor) - {} - - bool AddItemTo(ShaderRenderPass* aPass) const; - - gfx::Color mColor; -}; - -struct TexturedTraits : public SimpleTraits -{ - TexturedTraits(const gfx::Rect& aRect, const gfx::Rect& aTexCoords) - : SimpleTraits(aRect), mTexCoords(aTexCoords) - {} - - bool AddVerticesTo(ShaderRenderPass* aPass, - const ItemInfo& aItem, - uint32_t aItemIndex, - const gfx::Polygon* aGeometry = nullptr) const; - bool AddItemTo(ShaderRenderPass* aPass) const; - - gfx::Rect mTexCoords; -}; - -} // namespace mlg -} // namespace layers -} // namespace mozilla - -#endif diff --git a/gfx/layers/mlgpu/SharedBufferMLGPU.cpp b/gfx/layers/mlgpu/SharedBufferMLGPU.cpp deleted file mode 100644 index 7cac74058662..000000000000 --- a/gfx/layers/mlgpu/SharedBufferMLGPU.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "SharedBufferMLGPU.h" -#include "BufferCache.h" -#include "MLGDevice.h" - -using namespace std; - -namespace mozilla { -namespace layers { - -SharedBufferMLGPU::SharedBufferMLGPU(MLGDevice* aDevice, MLGBufferType aType, size_t aDefaultSize) - : mDevice(aDevice), - mType(aType), - mDefaultSize(aDefaultSize), - mCanUseOffsetAllocation(true), - mCurrentPosition(0), - mMaxSize(0), - mMapped(false), - mBytesUsedThisFrame(0), - mNumSmallFrames(0) -{ - MOZ_COUNT_CTOR(SharedBufferMLGPU); -} - -SharedBufferMLGPU::~SharedBufferMLGPU() -{ - MOZ_COUNT_DTOR(SharedBufferMLGPU); - Unmap(); -} - -bool -SharedBufferMLGPU::Init() -{ - // If we can't use buffer offset binding, we never allocated shared buffers. - if (!mCanUseOffsetAllocation) { - return true; - } - - // If we can use offset binding, allocate an initial shared buffer now. - if (!GrowBuffer(mDefaultSize)) { - return false; - } - return true; -} - -void -SharedBufferMLGPU::Reset() -{ - // We shouldn't be mapped here, but just in case, unmap now. - Unmap(); - mBytesUsedThisFrame = 0; - - // If we allocated a large buffer for a particularly heavy layer tree, - // but have not used most of the buffer again for many frames, we - // discard the buffer. This is to prevent having to perform large - // pointless uploads after visiting a single havy page - it also - // lessens ping-ponging between large and small buffers. - if (mBuffer && - (mBuffer->GetSize() > mDefaultSize * 4) && - mNumSmallFrames >= 10) - { - mBuffer = nullptr; - } - - // Note that we do not aggressively map a new buffer. There's no reason to, - // and it'd cause unnecessary uploads when painting empty frames. -} - -bool -SharedBufferMLGPU::EnsureMappedBuffer(size_t aBytes) -{ - if (!mBuffer || (mMaxSize - mCurrentPosition < aBytes)) { - if (!GrowBuffer(aBytes)) { - return false; - } - } - if (!mMapped && !Map()) { - return false; - } - return true; -} - -// We don't want to cache large buffers, since it results in larger uploads -// that might not be needed. -static const size_t kMaxCachedBufferSize = 128 * 1024; - -bool -SharedBufferMLGPU::GrowBuffer(size_t aBytes) -{ - // We only pre-allocate buffers if we can use offset allocation. - MOZ_ASSERT(mCanUseOffsetAllocation); - - // Unmap the previous buffer. This will retain mBuffer, but free up the - // address space used by its mapping. - Unmap(); - - size_t maybeSize = mDefaultSize; - if (mBuffer) { - // Try to first grow the previous allocation size. - maybeSize = std::min(kMaxCachedBufferSize, mBuffer->GetSize() * 2); - } - - size_t bytes = std::max(aBytes, maybeSize); - mBuffer = mDevice->CreateBuffer(mType, bytes, MLGUsage::Dynamic); - if (!mBuffer) { - return false; - } - - mCurrentPosition = 0; - mMaxSize = mBuffer->GetSize(); - return true; -} - -void -SharedBufferMLGPU::PrepareForUsage() -{ - Unmap(); - - if (mBytesUsedThisFrame <= mDefaultSize) { - mNumSmallFrames++; - } else { - mNumSmallFrames = 0; - } -} - -bool -SharedBufferMLGPU::Map() -{ - MOZ_ASSERT(mBuffer); - MOZ_ASSERT(!mMapped); - - if (!mDevice->Map(mBuffer, MLGMapType::WRITE_DISCARD, &mMap)) { - // Don't retain the buffer, it's useless if we can't map it. - mBuffer = nullptr; - return false; - } - - mCurrentPosition = 0; - mMapped = true; - return true; -} - -void -SharedBufferMLGPU::Unmap() -{ - if (!mMapped) { - return; - } - - mBytesUsedThisFrame += mCurrentPosition; - - mDevice->Unmap(mBuffer); - mMap = MLGMappedResource(); - mMapped = false; -} - -SharedVertexBuffer::SharedVertexBuffer(MLGDevice* aDevice, size_t aDefaultSize) - : SharedBufferMLGPU(aDevice, MLGBufferType::Vertex, aDefaultSize) -{ -} - -SharedConstantBuffer::SharedConstantBuffer(MLGDevice* aDevice, size_t aDefaultSize) - : SharedBufferMLGPU(aDevice, MLGBufferType::Constant, aDefaultSize) -{ - mMaxConstantBufferBindSize = aDevice->GetMaxConstantBufferBindSize(); - mCanUseOffsetAllocation = aDevice->CanUseConstantBufferOffsetBinding(); -} - -uint8_t* -SharedConstantBuffer::AllocateNewBuffer(size_t aBytes, ptrdiff_t* aOutOffset, RefPtr* aOutBuffer) -{ - RefPtr buffer; - if (BufferCache* cache = mDevice->GetConstantBufferCache()) { - buffer = cache->GetOrCreateBuffer(aBytes); - } else { - buffer = mDevice->CreateBuffer(MLGBufferType::Constant, aBytes, MLGUsage::Dynamic); - } - if (!buffer) { - return nullptr; - } - - MLGMappedResource map; - if (!mDevice->Map(buffer, MLGMapType::WRITE_DISCARD, &map)) { - return nullptr; - } - - // Signal that offsetting is not supported. - *aOutOffset = -1; - *aOutBuffer = buffer; - return reinterpret_cast(map.mData); -} - -void -AutoBufferUploadBase::UnmapBuffer() -{ - mDevice->Unmap(mBuffer); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/SharedBufferMLGPU.h b/gfx/layers/mlgpu/SharedBufferMLGPU.h deleted file mode 100644 index 5254f2b5a833..000000000000 --- a/gfx/layers/mlgpu/SharedBufferMLGPU.h +++ /dev/null @@ -1,372 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_SharedBufferMLGPU_h -#define mozilla_gfx_layers_mlgpu_SharedBufferMLGPU_h - -#include "ShaderDefinitionsMLGPU.h" -#include "MLGDeviceTypes.h" -#include "StagingBuffer.h" -#include "mozilla/gfx/Logging.h" - -namespace mozilla { -namespace layers { - -class MLGBuffer; - -class SharedBufferMLGPU -{ -public: - virtual ~SharedBufferMLGPU(); - - bool Init(); - - // Call before starting a new frame. - void Reset(); - - // Call to finish any pending uploads. - void PrepareForUsage(); - -protected: - SharedBufferMLGPU(MLGDevice* aDevice, MLGBufferType aType, size_t aDefaultSize); - - bool EnsureMappedBuffer(size_t aBytes); - bool GrowBuffer(size_t aBytes); - void ForgetBuffer(); - bool Map(); - void Unmap(); - - uint8_t* GetBufferPointer(size_t aBytes, ptrdiff_t* aOutOffset, RefPtr* aOutBuffer) { - if (!EnsureMappedBuffer(aBytes)) { - return nullptr; - } - - ptrdiff_t newPos = mCurrentPosition + aBytes; - MOZ_ASSERT(size_t(newPos) <= mMaxSize); - - *aOutOffset = mCurrentPosition; - *aOutBuffer = mBuffer; - - uint8_t* ptr = reinterpret_cast(mMap.mData) + mCurrentPosition; - mCurrentPosition = newPos; - return ptr; - } - -protected: - // Note: RefPtr here would cause a cycle. Only MLGDevice should own - // SharedBufferMLGPU objects for now. - MLGDevice* mDevice; - MLGBufferType mType; - size_t mDefaultSize; - bool mCanUseOffsetAllocation; - - // When |mBuffer| is non-null, mMaxSize is the buffer size. If mapped, the - // position is between 0 and mMaxSize, otherwise it is always 0. - RefPtr mBuffer; - ptrdiff_t mCurrentPosition; - size_t mMaxSize; - - MLGMappedResource mMap; - bool mMapped; - - // These are used to track how many frames come in under the default - // buffer size in a row. - size_t mBytesUsedThisFrame; - size_t mNumSmallFrames; -}; - -class VertexBufferSection final -{ - friend class SharedVertexBuffer; -public: - VertexBufferSection() - : mOffset(-1), - mNumVertices(0), - mStride(0) - {} - - uint32_t Stride() const { - return mStride; - } - MLGBuffer* GetBuffer() const { - return mBuffer; - } - ptrdiff_t Offset() const { - MOZ_ASSERT(IsValid()); - return mOffset; - } - size_t NumVertices() const { - return mNumVertices; - } - bool IsValid() const { - return !!mBuffer; - } - -protected: - void Init(MLGBuffer* aBuffer, ptrdiff_t aOffset, size_t aNumVertices, size_t aStride) { - mBuffer = aBuffer; - mOffset = aOffset; - mNumVertices = aNumVertices; - mStride = aStride; - } - -protected: - RefPtr mBuffer; - ptrdiff_t mOffset; - size_t mNumVertices; - size_t mStride; -}; - -class ConstantBufferSection final -{ - friend class SharedConstantBuffer; - -public: - ConstantBufferSection() - : mOffset(-1) - {} - - uint32_t NumConstants() const { - return NumConstantsForBytes(mNumBytes); - } - size_t NumItems() const { - return mNumItems; - } - uint32_t Offset() const { - MOZ_ASSERT(IsValid()); - return mOffset / 16; - } - MLGBuffer* GetBuffer() const { - return mBuffer; - } - bool IsValid() const { - return !!mBuffer; - } - bool HasOffset() const { - return mOffset != -1; - } - -protected: - static constexpr size_t NumConstantsForBytes(size_t aBytes) { - return (aBytes + ((256 - (aBytes % 256)) % 256)) / 16; - } - - void Init(MLGBuffer* aBuffer, ptrdiff_t aOffset, size_t aBytes, size_t aNumItems) { - mBuffer = aBuffer; - mOffset = aOffset; - mNumBytes = aBytes; - mNumItems = aNumItems; - } - -protected: - RefPtr mBuffer; - ptrdiff_t mOffset; - size_t mNumBytes; - size_t mNumItems; -}; - -// Vertex buffers don't need special alignment. -typedef StagingBuffer<0> VertexStagingBuffer; - -class SharedVertexBuffer final : public SharedBufferMLGPU -{ -public: - SharedVertexBuffer(MLGDevice* aDevice, size_t aDefaultSize); - - // Allocate a buffer that can be uploaded immediately. - bool Allocate(VertexBufferSection* aHolder, const VertexStagingBuffer& aStaging) { - return Allocate(aHolder, - aStaging.NumItems(), - aStaging.SizeOfItem(), - aStaging.GetBufferStart()); - } - - // Allocate a buffer that can be uploaded immediately. This is the - // direct access version, for cases where a StagingBuffer is not - // needed. - bool Allocate(VertexBufferSection* aHolder, - size_t aNumItems, - size_t aSizeOfItem, - const void* aData) - { - RefPtr buffer; - ptrdiff_t offset; - size_t bytes = aSizeOfItem * aNumItems; - uint8_t* ptr = GetBufferPointer(bytes, &offset, &buffer); - if (!ptr) { - return false; - } - - memcpy(ptr, aData, bytes); - aHolder->Init(buffer, offset, aNumItems, aSizeOfItem); - return true; - } - - template - bool Allocate(VertexBufferSection* aHolder, const T& aItem) { - return Allocate(aHolder, 1, sizeof(T), &aItem); - } -}; - -// To support older Direct3D versions, we need to support one-off MLGBuffers, -// where data is uploaded immediately rather than at the end of all batch -// preparation. We achieve this through a small helper class. -// -// Note: the unmap is not inline sincce we don't include MLGDevice.h. -class MOZ_STACK_CLASS AutoBufferUploadBase -{ -public: - AutoBufferUploadBase() : mPtr(nullptr) {} - ~AutoBufferUploadBase() { - if (mBuffer) { - UnmapBuffer(); - } - } - - void Init(void* aPtr) { - MOZ_ASSERT(!mPtr && aPtr); - mPtr = aPtr; - } - void Init(void* aPtr, MLGDevice* aDevice, MLGBuffer* aBuffer) { - MOZ_ASSERT(!mPtr && aPtr); - mPtr = aPtr; - mDevice = aDevice; - mBuffer = aBuffer; - } - void* get() { - return const_cast(mPtr); - } - -private: - void UnmapBuffer(); - -protected: - RefPtr mDevice; - RefPtr mBuffer; - void* mPtr; -}; - -// This is a typed helper for AutoBufferUploadBase. -template -class AutoBufferUpload : public AutoBufferUploadBase -{ -public: - AutoBufferUpload() - {} - - T* operator ->() const { - return reinterpret_cast(mPtr); - } -}; - -class SharedConstantBuffer final : public SharedBufferMLGPU -{ -public: - SharedConstantBuffer(MLGDevice* aDevice, size_t aDefaultSize); - - // Allocate a buffer that can be immediately uploaded. - bool Allocate(ConstantBufferSection* aHolder, const ConstantStagingBuffer& aStaging) { - MOZ_ASSERT(aStaging.NumItems() * aStaging.SizeOfItem() == aStaging.NumBytes()); - return Allocate(aHolder, aStaging.NumItems(), aStaging.SizeOfItem(), aStaging.GetBufferStart()); - } - - // Allocate a buffer of one item that can be immediately uploaded. - template - bool Allocate(ConstantBufferSection* aHolder, const T& aItem) { - return Allocate(aHolder, 1, sizeof(aItem), &aItem); - } - - // Allocate a buffer of N items that can be immediately uploaded. - template - bool Allocate(ConstantBufferSection* aHolder, const T* aItems, size_t aNumItems) { - return Allocate(aHolder, aNumItems, sizeof(T), aItems); - } - - // Allocate a buffer that is uploaded after the caller has finished writing - // to it. This should method should generally not be used unless copying T - // is expensive, since the default immediate-upload version has an implicit - // extra copy to the GPU. This version exposes the mapped memory directly. - template - bool Allocate(ConstantBufferSection* aHolder, AutoBufferUpload* aPtr) { - MOZ_ASSERT(sizeof(T) % 16 == 0, "Items must be padded to 16 bytes"); - - return Allocate(aHolder, aPtr, 1, sizeof(T)); - } - -private: - bool Allocate(ConstantBufferSection* aHolder, - size_t aNumItems, - size_t aSizeOfItem, - const void* aData) - { - AutoBufferUploadBase ptr; - if (!Allocate(aHolder, &ptr, aNumItems, aSizeOfItem)) { - return false; - } - memcpy(ptr.get(), aData, aNumItems * aSizeOfItem); - return true; - } - - bool Allocate(ConstantBufferSection* aHolder, - AutoBufferUploadBase* aPtr, - size_t aNumItems, - size_t aSizeOfItem) - { - MOZ_ASSERT(aSizeOfItem % 16 == 0, "Items must be padded to 16 bytes"); - - size_t bytes = aNumItems * aSizeOfItem; - if (bytes > mMaxConstantBufferBindSize) { - gfxWarning() << "Attempted to allocate too many bytes into a constant buffer"; - return false; - } - - - RefPtr buffer; - ptrdiff_t offset; - if (!GetBufferPointer(aPtr, bytes, &offset, &buffer)) { - return false; - } - - aHolder->Init(buffer, offset, bytes, aNumItems); - return true; - } - - bool GetBufferPointer(AutoBufferUploadBase* aPtr, - size_t aBytes, - ptrdiff_t* aOutOffset, - RefPtr* aOutBuffer) - { - if (!mCanUseOffsetAllocation) { - uint8_t* ptr = AllocateNewBuffer(aBytes, aOutOffset, aOutBuffer); - if (!ptr) { - return false; - } - aPtr->Init(ptr, mDevice, *aOutBuffer); - return true; - } - - // Align up the allocation to 256 bytes, since D3D11 requires that - // constant buffers start at multiples of 16 elements. - size_t alignedBytes = AlignUp<256>::calc(aBytes); - - uint8_t* ptr = SharedBufferMLGPU::GetBufferPointer(alignedBytes, aOutOffset, aOutBuffer); - if (!ptr) { - return false; - } - - aPtr->Init(ptr); - return true; - } - - uint8_t* AllocateNewBuffer(size_t aBytes, ptrdiff_t* aOutOffset, RefPtr* aOutBuffer); - -private: - size_t mMaxConstantBufferBindSize; -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_SharedBufferMLGPU_h diff --git a/gfx/layers/mlgpu/StagingBuffer.cpp b/gfx/layers/mlgpu/StagingBuffer.cpp deleted file mode 100644 index e032af5baab0..000000000000 --- a/gfx/layers/mlgpu/StagingBuffer.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "StagingBuffer.h" -#include "MLGDevice.h" -#include "ShaderDefinitionsMLGPU.h" - -namespace mozilla { -namespace layers { - -ConstantStagingBuffer::ConstantStagingBuffer(MLGDevice* aDevice) - : StagingBuffer(mlg::kMaxConstantBufferSize) -{ -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/StagingBuffer.h b/gfx/layers/mlgpu/StagingBuffer.h deleted file mode 100644 index bb9a312e19c0..000000000000 --- a/gfx/layers/mlgpu/StagingBuffer.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_StagingBuffer_h -#define mozilla_gfx_layers_mlgpu_StagingBuffer_h - -#include "mozilla/UniquePtr.h" -#include "UtilityMLGPU.h" -#include -#include -#include - -namespace mozilla { -namespace layers { - -class MLGDevice; - -// A StagingBuffer is a writable memory buffer for arbitrary contents. -template -class StagingBuffer -{ -public: - StagingBuffer() - : StagingBuffer(0) - {} - - // By default, staging buffers operate in "forward" mode: items are added to - // the end of the buffer. In "reverse" mode the cursor is at the end of the - // buffer, and items are added to the beginning. - // - // This must be called before the buffer is written. - void SetReversed() { - MOZ_ASSERT(IsEmpty()); - mReversed = true; - } - - // Write a series of components as a single item. When this is first used, the - // buffer records the initial item size and requires that all future items be - // the exact same size. - // - // This directs to either AppendItem or PrependItem depending on the buffer - // state. - template - bool AddItem(const T& aItem) { - if (mReversed) { - return PrependItem(aItem); - } - return AppendItem(aItem); - } - - // This may only be called on forward buffers. - template - bool AppendItem(const T& aItem) { - MOZ_ASSERT(!mReversed); - - size_t alignedBytes = AlignUp::calc(sizeof(aItem)); - if (!mUniformSize) { - mUniformSize = alignedBytes; - } - - if (!EnsureForwardRoomFor(alignedBytes)) { - return false; - } - if (mUniformSize != alignedBytes) { - MOZ_ASSERT_UNREACHABLE("item of incorrect size added!"); - return false; - } - - *reinterpret_cast(mPos) = aItem; - mPos += alignedBytes; - MOZ_ASSERT(mPos <= mEnd); - - mNumItems++; - return true; - } - - // This may only be called on reversed buffers. - template - bool PrependItem(const T& aItem) { - MOZ_ASSERT(mReversed); - - size_t alignedBytes = AlignUp::calc(sizeof(aItem)); - if (!mUniformSize) { - mUniformSize = alignedBytes; - } - - if (!EnsureBackwardRoomFor(alignedBytes)) { - return false; - } - if (mUniformSize != alignedBytes) { - MOZ_ASSERT_UNREACHABLE("item of incorrect size added!"); - return false; - } - - mPos -= alignedBytes; - *reinterpret_cast(mPos) = aItem; - MOZ_ASSERT(mPos >= mBuffer.get()); - - mNumItems++; - return true; - } - - size_t NumBytes() const { - return mReversed - ? mEnd - mPos - : mPos - mBuffer.get(); - } - uint8_t* GetBufferStart() const { - return mReversed - ? mPos - : mBuffer.get(); - } - size_t SizeOfItem() const { - return mUniformSize; - } - size_t NumItems() const { - return mNumItems; - } - - void Reset() { - mPos = mReversed ? mEnd : mBuffer.get(); - mUniformSize = 0; - mNumItems = 0; - } - - // RestorePosition must only be called with a previous call to - // GetPosition. - typedef std::pair Position; - Position GetPosition() const { - return std::make_pair(NumBytes(), mNumItems); - } - void RestorePosition(const Position& aPosition) { - mPos = mBuffer.get() + aPosition.first; - mNumItems = aPosition.second; - if (mNumItems == 0) { - mUniformSize = 0; - } - - // Make sure the buffer is still coherent. - MOZ_ASSERT(mPos >= mBuffer.get() && mPos <= mEnd); - MOZ_ASSERT(mNumItems * mUniformSize == NumBytes()); - } - - bool IsEmpty() const { - return mNumItems == 0; - } - -protected: - explicit StagingBuffer(size_t aMaxSize) - : mPos(nullptr), - mEnd(nullptr), - mUniformSize(0), - mNumItems(0), - mMaxSize(aMaxSize), - mReversed(false) - {} - - static const size_t kDefaultSize = 8; - - bool EnsureForwardRoomFor(size_t aAlignedBytes) { - if (size_t(mEnd - mPos) < aAlignedBytes) { - return GrowBuffer(aAlignedBytes); - } - return true; - } - - bool EnsureBackwardRoomFor(size_t aAlignedBytes) { - if (size_t(mPos - mBuffer.get()) < aAlignedBytes) { - return GrowBuffer(aAlignedBytes); - } - return true; - } - - bool GrowBuffer(size_t aAlignedBytes) { - // We should not be writing items that are potentially bigger than the - // maximum constant buffer size, that's crazy. An assert should be good - // enough since the size of writes is static - and shader compilers - // would explode anyway. - MOZ_ASSERT_IF(mMaxSize, aAlignedBytes < mMaxSize); - MOZ_ASSERT_IF(mMaxSize, kDefaultSize * Alignment < mMaxSize); - - if (!mBuffer) { - size_t newSize = std::max(kDefaultSize * Alignment, aAlignedBytes); - MOZ_ASSERT_IF(mMaxSize, newSize < mMaxSize); - - mBuffer = MakeUnique(newSize); - mEnd = mBuffer.get() + newSize; - mPos = mReversed ? mEnd : mBuffer.get(); - return true; - } - - // Take the bigger of exact-fit or 1.5x the previous size, and make sure - // the new size doesn't overflow size_t. If needed, clamp to the max - // size. - size_t oldSize = mEnd - mBuffer.get(); - size_t trySize = std::max(oldSize + aAlignedBytes, oldSize + oldSize / 2); - size_t newSize = mMaxSize ? std::min(trySize, mMaxSize) : trySize; - if (newSize < oldSize || newSize - oldSize < aAlignedBytes) { - return false; - } - - UniquePtr newBuffer = MakeUnique(newSize); - if (!newBuffer) { - return false; - } - - // When the buffer is in reverse mode, we have to copy from the end of the - // buffer, not the beginning. - if (mReversed) { - size_t usedBytes = mEnd - mPos; - size_t newPos = newSize - usedBytes; - MOZ_RELEASE_ASSERT(newPos + usedBytes <= newSize); - - memcpy(newBuffer.get() + newPos, mPos, usedBytes); - mPos = newBuffer.get() + newPos; - } else { - size_t usedBytes = mPos - mBuffer.get(); - MOZ_RELEASE_ASSERT(usedBytes <= newSize); - - memcpy(newBuffer.get(), mBuffer.get(), usedBytes); - mPos = newBuffer.get() + usedBytes; - } - mEnd = newBuffer.get() + newSize; - mBuffer = Move(newBuffer); - - MOZ_RELEASE_ASSERT(mPos >= mBuffer.get() && mPos <= mEnd); - return true; - } - -protected: - UniquePtr mBuffer; - uint8_t* mPos; - uint8_t* mEnd; - size_t mUniformSize; - size_t mNumItems; - size_t mMaxSize; - bool mReversed; -}; - -class ConstantStagingBuffer : public StagingBuffer<16> -{ - public: - explicit ConstantStagingBuffer(MLGDevice* aDevice); -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_StagingBuffer_h diff --git a/gfx/layers/mlgpu/TextureSourceProviderMLGPU.cpp b/gfx/layers/mlgpu/TextureSourceProviderMLGPU.cpp deleted file mode 100644 index 47a87ff81d8d..000000000000 --- a/gfx/layers/mlgpu/TextureSourceProviderMLGPU.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "TextureSourceProviderMLGPU.h" -#include "LayerManagerMLGPU.h" -#include "MLGDevice.h" -#ifdef XP_WIN -# include "mozilla/layers/MLGDeviceD3D11.h" -#endif - -namespace mozilla { -namespace layers { - -TextureSourceProviderMLGPU::TextureSourceProviderMLGPU(LayerManagerMLGPU* aLayerManager, MLGDevice* aDevice) - : mLayerManager(aLayerManager), - mDevice(aDevice) -{ -} - -TextureSourceProviderMLGPU::~TextureSourceProviderMLGPU() -{ -} - -int32_t -TextureSourceProviderMLGPU::GetMaxTextureSize() const -{ - if (!mDevice) { - return 0; - } - return mDevice->GetMaxTextureSize(); -} - -bool -TextureSourceProviderMLGPU::SupportsEffect(EffectTypes aEffect) -{ - switch (aEffect) { - case EffectTypes::YCBCR: - return true; - default: - MOZ_ASSERT_UNREACHABLE("NYI"); - } - return false; -} - -bool -TextureSourceProviderMLGPU::IsValid() const -{ - return !!mLayerManager; -} - -void -TextureSourceProviderMLGPU::Destroy() -{ - mLayerManager = nullptr; - mDevice = nullptr; - TextureSourceProvider::Destroy(); -} - -#ifdef XP_WIN -ID3D11Device* -TextureSourceProviderMLGPU::GetD3D11Device() const -{ - if (!mDevice) { - return nullptr; - } - return mDevice->AsD3D11()->GetD3D11Device(); -} -#endif - -TimeStamp -TextureSourceProviderMLGPU::GetLastCompositionEndTime() const -{ - if (!mLayerManager) { - return TimeStamp(); - } - return mLayerManager->GetLastCompositionEndTime(); -} - -already_AddRefed -TextureSourceProviderMLGPU::CreateDataTextureSource(TextureFlags aFlags) -{ - RefPtr texture = mDevice->CreateDataTextureSource(aFlags); - return texture.forget(); -} - -already_AddRefed -TextureSourceProviderMLGPU::CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) -{ - MOZ_ASSERT_UNREACHABLE("NYI"); - return nullptr; -} - -bool -TextureSourceProviderMLGPU::NotifyNotUsedAfterComposition(TextureHost* aTextureHost) -{ - if (!mDevice) { - return false; - } - return TextureSourceProvider::NotifyNotUsedAfterComposition(aTextureHost); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/TextureSourceProviderMLGPU.h b/gfx/layers/mlgpu/TextureSourceProviderMLGPU.h deleted file mode 100644 index 2351c3681720..000000000000 --- a/gfx/layers/mlgpu/TextureSourceProviderMLGPU.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_TextureSourceProviderMLGPU_h -#define mozilla_gfx_layers_mlgpu_TextureSourceProviderMLGPU_h - -#include "mozilla/layers/TextureSourceProvider.h" - -namespace mozilla { -namespace layers { - -class MLGDevice; -class LayerManagerMLGPU; - -class TextureSourceProviderMLGPU final : public TextureSourceProvider -{ -public: - TextureSourceProviderMLGPU(LayerManagerMLGPU* aLayerManager, MLGDevice* aDevice); - ~TextureSourceProviderMLGPU() override; - - already_AddRefed - CreateDataTextureSource(TextureFlags aFlags) override; - - already_AddRefed - CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) override; - - bool NotifyNotUsedAfterComposition(TextureHost* aTextureHost) override; - - int32_t GetMaxTextureSize() const override; - TimeStamp GetLastCompositionEndTime() const override; - bool SupportsEffect(EffectTypes aEffect) override; - bool IsValid() const override; - -#ifdef XP_WIN - virtual ID3D11Device* GetD3D11Device() const override; -#endif - - void ReadUnlockTextures() { - TextureSourceProvider::ReadUnlockTextures(); - } - - // Release references to the layer manager. - void Destroy() override; - -private: - // Using RefPtr<> here would be a circular reference. - LayerManagerMLGPU* mLayerManager; - RefPtr mDevice; -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_TextureSourceProviderMLGPU_h diff --git a/gfx/layers/mlgpu/TexturedLayerMLGPU.cpp b/gfx/layers/mlgpu/TexturedLayerMLGPU.cpp deleted file mode 100644 index d6c3fbc50444..000000000000 --- a/gfx/layers/mlgpu/TexturedLayerMLGPU.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "TexturedLayerMLGPU.h" -#include "LayerManagerMLGPU.h" -#include "RenderViewMLGPU.h" -#include "FrameBuilder.h" -#include "mozilla/gfx/Types.h" -#include "mozilla/layers/ImageHost.h" -#include "UnitTransforms.h" - -namespace mozilla { -namespace layers { - -using namespace gfx; - -TexturedLayerMLGPU::TexturedLayerMLGPU(LayerManagerMLGPU* aManager) - : LayerMLGPU(aManager) -{ -} - -TexturedLayerMLGPU::~TexturedLayerMLGPU() -{ - // Note: we have to cleanup resources in derived classes, since we can't - // easily tell in our destructor if we have a TempImageLayerMLGPU, which - // should not have its compositable detached, and we can't call GetLayer - // here. -} - -bool -TexturedLayerMLGPU::SetCompositableHost(CompositableHost* aHost) -{ - switch (aHost->GetType()) { - case CompositableType::IMAGE: - mHost = aHost->AsImageHost(); - return true; - default: - return false; - } -} - -CompositableHost* -TexturedLayerMLGPU::GetCompositableHost() -{ - if (mHost && mHost->IsAttached()) { - return mHost.get(); - } - return nullptr; -} - -RefPtr -TexturedLayerMLGPU::BindAndGetTexture() -{ - if (!mHost) { - return nullptr; - } - - LayerManagerMLGPU* lm = GetLayerManager()->AsLayerManagerMLGPU(); - - // Note: we don't call FinishRendering since mask layers do not need - // composite notifications or bias updates. (This function should - // not be called for non-mask-layers). - ImageHost::RenderInfo info; - if (!mHost->PrepareToRender(lm->GetTextureSourceProvider(), &info)) { - return nullptr; - } - - RefPtr source = mHost->AcquireTextureSource(info); - if (!source) { - return nullptr; - } - - mTexture = source; - return source; -} - -bool -TexturedLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder) -{ - if (!mHost) { - return false; - } - - LayerManagerMLGPU* lm = GetLayerManager()->AsLayerManagerMLGPU(); - - ImageHost::RenderInfo info; - if (!mHost->PrepareToRender(lm->GetTextureSourceProvider(), &info)) { - return false; - } - - RefPtr source = mHost->AcquireTextureSource(info); - if (!source) { - return false; - } - - if (source->AsBigImageIterator()) { - mBigImageTexture = source; - mTexture = nullptr; - } else { - mTexture = source; - } - - mPictureRect = IntRect(0, 0, info.img->mPictureRect.width, info.img->mPictureRect.height); - - mHost->FinishRendering(info); - return true; -} - -void -TexturedLayerMLGPU::AssignToView(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - Maybe&& aGeometry) -{ - if (mBigImageTexture) { - BigImageIterator* iter = mBigImageTexture->AsBigImageIterator(); - iter->BeginBigImageIteration(); - AssignBigImage(aBuilder, aView, iter, aGeometry); - iter->EndBigImageIteration(); - } else { - LayerMLGPU::AssignToView(aBuilder, aView, Move(aGeometry)); - } -} - -void -TexturedLayerMLGPU::AssignBigImage(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - BigImageIterator* aIter, - const Maybe& aGeometry) -{ - const Matrix4x4& transform = GetLayer()->GetEffectiveTransformForBuffer(); - - // Note that we don't need to assign these in any particular order, since - // they do not overlap. - do { - IntRect tileRect = aIter->GetTileRect(); - IntRect rect = tileRect.Intersect(mPictureRect); - if (rect.IsEmpty()) { - continue; - } - - { - Rect screenRect = transform.TransformBounds(Rect(rect)); - screenRect.MoveBy(-aView->GetTargetOffset()); - screenRect = screenRect.Intersect(Rect(mComputedClipRect.ToUnknownRect())); - if (screenRect.IsEmpty()) { - // This tile is not in the clip region, so skip it. - continue; - } - } - - RefPtr tile = mBigImageTexture->ExtractCurrentTile(); - if (!tile) { - continue; - } - - // Create a temporary item. - RefPtr item = new TempImageLayerMLGPU(aBuilder->GetManager()); - item->Init(this, tile, rect); - - Maybe geometry = aGeometry; - item->AddBoundsToView(aBuilder, aView, Move(geometry)); - - // Since the layer tree is not holding this alive, we have to ask the - // FrameBuilder to do it for us. - aBuilder->RetainTemporaryLayer(item); - } while (aIter->NextTile()); -} - -TempImageLayerMLGPU::TempImageLayerMLGPU(LayerManagerMLGPU* aManager) - : ImageLayer(aManager, static_cast(this)), - TexturedLayerMLGPU(aManager) -{ -} - -TempImageLayerMLGPU::~TempImageLayerMLGPU() -{ -} - -void -TempImageLayerMLGPU::Init(TexturedLayerMLGPU* aSource, - const RefPtr& aTexture, - const gfx::IntRect& aPictureRect) -{ - // ImageLayer properties. - mEffectiveTransform = aSource->GetLayer()->GetEffectiveTransform(); - mEffectiveTransformForBuffer = aSource->GetLayer()->GetEffectiveTransformForBuffer(); - - // Base LayerMLGPU properties. - mComputedClipRect = aSource->GetComputedClipRect(); - mMask = aSource->GetMask(); - mComputedOpacity = aSource->GetComputedOpacity(); - - // TexturedLayerMLGPU properties. - mHost = aSource->GetImageHost(); - mTexture = aTexture; - mPictureRect = aPictureRect; - - // Local properties. - mFilter = aSource->GetSamplingFilter(); - mShadowVisibleRegion = aSource->GetShadowVisibleRegion(); - mIsOpaque = aSource->IsContentOpaque(); - - // Set this layer to prepared so IsPrepared() assertions don't fire. - MarkPrepared(); -} - -} // namespace layers -} // namespace mozilla diff --git a/gfx/layers/mlgpu/TexturedLayerMLGPU.h b/gfx/layers/mlgpu/TexturedLayerMLGPU.h deleted file mode 100644 index 8116a569641b..000000000000 --- a/gfx/layers/mlgpu/TexturedLayerMLGPU.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_TexturedLayerMLGPU_h -#define mozilla_gfx_layers_mlgpu_TexturedLayerMLGPU_h - -#include "LayerMLGPU.h" -#include "ImageLayers.h" -#include "mozilla/layers/ImageHost.h" - -namespace mozilla { -namespace layers { - -// This is the base class for canvas and image layers. -class TexturedLayerMLGPU : public LayerMLGPU -{ -public: - TexturedLayerMLGPU* AsTexturedLayerMLGPU() override { return this; } - - virtual gfx::SamplingFilter GetSamplingFilter() = 0; - - bool SetCompositableHost(CompositableHost* aHost) override; - CompositableHost* GetCompositableHost() override; - - void AssignToView(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - Maybe&& aGeometry) override; - - TextureSource* GetTexture() const { - return mTexture; - } - ImageHost* GetImageHost() const { - return mHost; - } - - // Return the scale factor from the texture source to the picture rect. - virtual Maybe GetPictureScale() const { - return Nothing(); - } - - // Mask layers aren't prepared like normal layers. They are bound as - // mask operations are built. Mask layers are never tiled (they are - // scaled to a lower resolution if too big), so this pathway returns - // a TextureSource. - RefPtr BindAndGetTexture(); - -protected: - explicit TexturedLayerMLGPU(LayerManagerMLGPU* aManager); - virtual ~TexturedLayerMLGPU() override; - - void AssignBigImage(FrameBuilder* aBuilder, - RenderViewMLGPU* aView, - BigImageIterator* aIter, - const Maybe& aGeometry); - - bool OnPrepareToRender(FrameBuilder* aBuilder) override; - -protected: - RefPtr mHost; - RefPtr mTexture; - RefPtr mBigImageTexture; - gfx::IntRect mPictureRect; -}; - -// This is a pseudo layer that wraps a tile in an ImageLayer backed by a -// BigImage. Without this, we wouldn't have anything sensible to add to -// RenderPasses. In the future we could potentially consume the source -// layer more intelligently instead (for example, having it compute -// which textures are relevant for a given tile). -class TempImageLayerMLGPU final : public ImageLayer, - public TexturedLayerMLGPU -{ -public: - explicit TempImageLayerMLGPU(LayerManagerMLGPU* aManager); - - // Layer - HostLayer* AsHostLayer() override { return this; } - gfx::SamplingFilter GetSamplingFilter() override { - return mFilter; - } - bool IsContentOpaque() override { - return mIsOpaque; - } - - void Init(TexturedLayerMLGPU* aSource, - const RefPtr& aTexture, - const gfx::IntRect& aPictureRect); - - // HostLayer - Layer* GetLayer() override { return this; } - -protected: - ~TempImageLayerMLGPU() override; - -private: - gfx::SamplingFilter mFilter; - bool mIsOpaque; -}; - -} // namespace layers -} // namespace mozilla - -#endif // mozilla_gfx_layers_mlgpu_TexturedLayerMLGPU_h diff --git a/gfx/layers/mlgpu/UtilityMLGPU.h b/gfx/layers/mlgpu/UtilityMLGPU.h deleted file mode 100644 index ae4aebb65b65..000000000000 --- a/gfx/layers/mlgpu/UtilityMLGPU.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- -* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_gfx_layers_mlgpu_UtilityMLGPU_h -#define mozilla_gfx_layers_mlgpu_UtilityMLGPU_h - -#include "mozilla/Assertions.h" -#include "mozilla/MathAlgorithms.h" - -namespace mozilla { -namespace layers { - -template struct AlignUp -{ - static inline size_t calc(size_t aAmount) { - MOZ_ASSERT(IsPowerOfTwo(T), "alignment must be a power of two"); - return aAmount + ((T - (aAmount % T)) % T); - } -}; - -template <> struct AlignUp<0> -{ - static inline size_t calc(size_t aAmount) { - return aAmount; - } -}; - -} // namespace layers -} // namespace mozilla - -#ifdef ENABLE_AL_LOGGING -# define AL_LOG(...) printf_stderr("AL: " __VA_ARGS__) -#else -# define AL_LOG(...) -#endif - -#endif // mozilla_gfx_layers_mlgpu_UtilityMLGPU_h diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 5c8cbe25167e..4166244fb128 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -66,14 +66,12 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': 'd3d11/DeviceAttachmentsD3D11.h', 'd3d11/DiagnosticsD3D11.h', 'd3d11/HelpersD3D11.h', - 'd3d11/MLGDeviceD3D11.h', 'd3d11/ReadbackManagerD3D11.h', 'd3d11/ShaderDefinitionsD3D11.h', 'd3d11/TextureD3D11.h', ] UNIFIED_SOURCES += [ 'd3d11/DiagnosticsD3D11.cpp', - 'd3d11/MLGDeviceD3D11.cpp', 'd3d11/TextureD3D11.cpp', ] SOURCES += [ @@ -150,7 +148,6 @@ EXPORTS.mozilla.layers += [ 'composite/ImageLayerComposite.h', 'composite/LayerManagerComposite.h', 'composite/PaintedLayerComposite.h', - 'composite/TextRenderer.h', 'composite/TextureHost.h', 'composite/TiledContentHost.h', 'Compositor.h', @@ -198,12 +195,6 @@ EXPORTS.mozilla.layers += [ 'LayerMetricsWrapper.h', 'LayersHelpers.h', 'LayersTypes.h', - 'mlgpu/LayerManagerMLGPU.h', - 'mlgpu/LayerMLGPU.h', - 'mlgpu/MLGDevice.h', - 'mlgpu/MLGDeviceTypes.h', - 'mlgpu/ShaderDefinitionsMLGPU.h', - 'mlgpu/UtilityMLGPU.h', 'opengl/CompositingRenderTargetOGL.h', 'opengl/CompositorOGL.h', 'opengl/MacIOSurfaceTextureClientOGL.h', @@ -403,23 +394,6 @@ UNIFIED_SOURCES += [ 'LayersLogging.cpp', 'LayerSorter.cpp', 'LayersTypes.cpp', - 'mlgpu/BufferCache.cpp', - 'mlgpu/CanvasLayerMLGPU.cpp', - 'mlgpu/ContainerLayerMLGPU.cpp', - 'mlgpu/FrameBuilder.cpp', - 'mlgpu/ImageLayerMLGPU.cpp', - 'mlgpu/LayerManagerMLGPU.cpp', - 'mlgpu/LayerMLGPU.cpp', - 'mlgpu/MaskOperation.cpp', - 'mlgpu/MLGDevice.cpp', - 'mlgpu/PaintedLayerMLGPU.cpp', - 'mlgpu/RenderPassMLGPU.cpp', - 'mlgpu/RenderViewMLGPU.cpp', - 'mlgpu/ShaderDefinitionsMLGPU.cpp', - 'mlgpu/SharedBufferMLGPU.cpp', - 'mlgpu/StagingBuffer.cpp', - 'mlgpu/TexturedLayerMLGPU.cpp', - 'mlgpu/TextureSourceProviderMLGPU.cpp', 'opengl/CompositingRenderTargetOGL.cpp', 'opengl/CompositorOGL.cpp', 'opengl/GLBlitTextureImageHelper.cpp', @@ -507,15 +481,11 @@ include('/ipc/chromium/chromium-config.mozbuild') if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': GENERATED_FILES = [ 'CompositorD3D11Shaders.h', - 'MLGShaders.h', ] d3d11_shaders = GENERATED_FILES['CompositorD3D11Shaders.h'] d3d11_shaders.script = 'd3d11/genshaders.py' d3d11_shaders.inputs = ['d3d11/shaders.manifest'] - mlg_shaders = GENERATED_FILES['MLGShaders.h'] - mlg_shaders.script = 'd3d11/genshaders.py' - mlg_shaders.inputs = ['d3d11/mlgshaders/shaders.manifest'] LOCAL_INCLUDES += [ '/docshell/base', # for nsDocShell.h diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 099867cf0e7f..7d6452be1428 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -560,13 +560,6 @@ private: DECL_GFX_PREF(Live, "layers.low-precision-opacity", LowPrecisionOpacity, float, 1.0f); DECL_GFX_PREF(Live, "layers.low-precision-resolution", LowPrecisionResolution, float, 0.25f); DECL_GFX_PREF(Live, "layers.max-active", MaxActiveLayers, int32_t, -1); - DECL_GFX_PREF(Once, "layers.mlgpu.dev-enabled", AdvancedLayersEnabledDoNotUseDirectly, bool, false); - DECL_GFX_PREF(Once, "layers.mlgpu.enable-buffer-cache", AdvancedLayersEnableBufferCache, bool, true); - DECL_GFX_PREF(Once, "layers.mlgpu.enable-buffer-sharing", AdvancedLayersEnableBufferSharing, bool, true); - DECL_GFX_PREF(Once, "layers.mlgpu.enable-clear-view", AdvancedLayersEnableClearView, bool, true); - DECL_GFX_PREF(Once, "layers.mlgpu.enable-cpu-occlusion", AdvancedLayersEnableCPUOcclusion, bool, true); - DECL_GFX_PREF(Once, "layers.mlgpu.enable-depth-buffer", AdvancedLayersEnableDepthBuffer, bool, false); - DECL_GFX_PREF(Live, "layers.mlgpu.enable-invalidation", AdvancedLayersUseInvalidation, bool, true); DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.force-disabled", LayersOffMainThreadCompositionForceDisabled, bool, false); DECL_GFX_PREF(Live, "layers.offmainthreadcomposition.frame-rate", LayersCompositionFrameRate, int32_t,-1); DECL_GFX_PREF(Live, "layers.orientation.sync.timeout", OrientationSyncMillis, uint32_t, (uint32_t)0); diff --git a/mfbt/EnumeratedArray.h b/mfbt/EnumeratedArray.h index f1525540921f..9e74b7724590 100644 --- a/mfbt/EnumeratedArray.h +++ b/mfbt/EnumeratedArray.h @@ -83,14 +83,6 @@ public: return mArray[size_t(aIndex)]; } - EnumeratedArray& operator =(EnumeratedArray&& aOther) - { - for (size_t i = 0; i < kSize; i++) { - mArray[i] = Move(aOther.mArray[i]); - } - return *this; - } - typedef typename ArrayType::iterator iterator; typedef typename ArrayType::const_iterator const_iterator; typedef typename ArrayType::reverse_iterator reverse_iterator; diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index c7e89808e0f8..3483522f0afe 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5716,14 +5716,6 @@ pref("dom.payments.request.enabled", false); pref("fuzzing.enabled", false); #endif -#if defined(XP_WIN) -pref("layers.mlgpu.dev-enabled", false); - -// Both this and the master "enabled" pref must be on to use Advanced LAyers -// on Windows 7. -pref("layers.mlgpu.enable-on-windows7", false); -#endif - // Set advanced layers preferences here to have them show up in about:config or // to be overridable in reftest.list files. They should pretty much all be set // to a value of 2, and the conditional-pref code in gfxPrefs.h will convert