forked from mirrors/gecko-dev
		
	 126bd9e1a4
			
		
	
	
		126bd9e1a4
		
	
	
	
	
		
			
			This patch was generated automatically by the "modeline.py" script, available here: https://github.com/amccreight/moz-source-tools/blob/master/modeline.py For every file that is modified in this patch, the changes are as follows: (1) The patch changes the file to use the exact C++ mode lines from the Mozilla coding style guide, available here: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style#Mode_Line (2) The patch deletes any blank lines between the mode line & the MPL boilerplate comment. (3) If the file previously had the mode lines and MPL boilerplate in a single contiguous C++ comment, then the patch splits them into separate C++ comments, to match the boilerplate in the coding style. MozReview-Commit-ID: 77D61xpSmIl --HG-- extra : rebase_source : c6162fa3cf539a07177a19838324bf368faa162b
		
			
				
	
	
		
			205 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* 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 "ExtendInputEffectD2D1.h"
 | |
| 
 | |
| #include "Logging.h"
 | |
| 
 | |
| #include "ShadersD2D1.h"
 | |
| #include "HelpersD2D.h"
 | |
| 
 | |
| #include <vector>
 | |
| 
 | |
| #define TEXTW(x) L##x
 | |
| #define XML(X) TEXTW(#X) // This macro creates a single string from multiple lines of text.
 | |
| 
 | |
| static const PCWSTR kXmlDescription =
 | |
|     XML(
 | |
|         <?xml version='1.0'?>
 | |
|         <Effect>
 | |
|             <!-- System Properties -->
 | |
|             <Property name='DisplayName' type='string' value='ExtendInputEffect'/>
 | |
|             <Property name='Author' type='string' value='Mozilla'/>
 | |
|             <Property name='Category' type='string' value='Utility Effects'/>
 | |
|             <Property name='Description' type='string' value='This effect is used to extend the output rect of any input effect to a specified rect.'/>
 | |
|             <Inputs>
 | |
|                 <Input name='InputEffect'/>
 | |
|             </Inputs>
 | |
|             <Property name='OutputRect' type='vector4'>
 | |
|               <Property name='DisplayName' type='string' value='Output Rect'/>
 | |
|             </Property>
 | |
|         </Effect>
 | |
|         );
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace gfx {
 | |
| 
 | |
| ExtendInputEffectD2D1::ExtendInputEffectD2D1()
 | |
|   : mRefCount(0)
 | |
|   , mOutputRect(D2D1::Vector4F(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX))
 | |
| {
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP
 | |
| ExtendInputEffectD2D1::Initialize(ID2D1EffectContext* pContextInternal, ID2D1TransformGraph* pTransformGraph)
 | |
| {
 | |
|   HRESULT hr;
 | |
|   hr = pTransformGraph->SetSingleTransformNode(this);
 | |
| 
 | |
|   if (FAILED(hr)) {
 | |
|     return hr;
 | |
|   }
 | |
| 
 | |
|   return S_OK;
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP
 | |
| ExtendInputEffectD2D1::PrepareForRender(D2D1_CHANGE_TYPE changeType)
 | |
| {
 | |
|   return S_OK;
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP
 | |
| ExtendInputEffectD2D1::SetGraph(ID2D1TransformGraph* pGraph)
 | |
| {
 | |
|   return E_NOTIMPL;
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP_(ULONG)
 | |
| ExtendInputEffectD2D1::AddRef()
 | |
| {
 | |
|   return ++mRefCount;
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP_(ULONG)
 | |
| ExtendInputEffectD2D1::Release()
 | |
| {
 | |
|   if (!--mRefCount) {
 | |
|     delete this;
 | |
|     return 0;
 | |
|   }
 | |
|   return mRefCount;
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP
 | |
| ExtendInputEffectD2D1::QueryInterface(const IID &aIID, void **aPtr)
 | |
| {
 | |
|   if (!aPtr) {
 | |
|     return E_POINTER;
 | |
|   }
 | |
| 
 | |
|   if (aIID == IID_IUnknown) {
 | |
|     *aPtr = static_cast<IUnknown*>(static_cast<ID2D1EffectImpl*>(this));
 | |
|   } else if (aIID == IID_ID2D1EffectImpl) {
 | |
|     *aPtr = static_cast<ID2D1EffectImpl*>(this);
 | |
|   } else if (aIID == IID_ID2D1DrawTransform) {
 | |
|     *aPtr = static_cast<ID2D1DrawTransform*>(this);
 | |
|   } else if (aIID == IID_ID2D1Transform) {
 | |
|     *aPtr = static_cast<ID2D1Transform*>(this);
 | |
|   } else if (aIID == IID_ID2D1TransformNode) {
 | |
|     *aPtr = static_cast<ID2D1TransformNode*>(this);
 | |
|   } else {
 | |
|     return E_NOINTERFACE;
 | |
|   }
 | |
| 
 | |
|   static_cast<IUnknown*>(*aPtr)->AddRef();
 | |
|   return S_OK;
 | |
| }
 | |
| 
 | |
| static D2D1_RECT_L
 | |
| ConvertFloatToLongRect(const D2D1_VECTOR_4F& aRect)
 | |
| {
 | |
|   // Clamp values to LONG range. We can't use std::min/max here because we want
 | |
|   // the comparison to operate on a type that's different from the type of the
 | |
|   // result.
 | |
|   return D2D1::RectL(aRect.x <= LONG_MIN ? LONG_MIN : LONG(aRect.x),
 | |
|                      aRect.y <= LONG_MIN ? LONG_MIN : LONG(aRect.y),
 | |
|                      aRect.z >= LONG_MAX ? LONG_MAX : LONG(aRect.z),
 | |
|                      aRect.w >= LONG_MAX ? LONG_MAX : LONG(aRect.w));
 | |
| }
 | |
| 
 | |
| static D2D1_RECT_L
 | |
| IntersectRect(const D2D1_RECT_L& aRect1, const D2D1_RECT_L& aRect2)
 | |
| {
 | |
|   return D2D1::RectL(std::max(aRect1.left, aRect2.left),
 | |
|                      std::max(aRect1.top, aRect2.top),
 | |
|                      std::min(aRect1.right, aRect2.right),
 | |
|                      std::min(aRect1.bottom, aRect2.bottom));
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP
 | |
| ExtendInputEffectD2D1::MapInputRectsToOutputRect(const D2D1_RECT_L* pInputRects,
 | |
|                                                  const D2D1_RECT_L* pInputOpaqueSubRects,
 | |
|                                                  UINT32 inputRectCount,
 | |
|                                                  D2D1_RECT_L* pOutputRect,
 | |
|                                                  D2D1_RECT_L* pOutputOpaqueSubRect)
 | |
| {
 | |
|   // This transform only accepts one input, so there will only be one input rect.
 | |
|   if (inputRectCount != 1) {
 | |
|     return E_INVALIDARG;
 | |
|   }
 | |
| 
 | |
|   // Set the output rect to the specified rect. This is the whole purpose of this effect.
 | |
|   *pOutputRect = ConvertFloatToLongRect(mOutputRect);
 | |
|   *pOutputOpaqueSubRect = IntersectRect(*pOutputRect, pInputOpaqueSubRects[0]);
 | |
|   return S_OK;
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP
 | |
| ExtendInputEffectD2D1::MapOutputRectToInputRects(const D2D1_RECT_L* pOutputRect,
 | |
|                                                  D2D1_RECT_L* pInputRects,
 | |
|                                                  UINT32 inputRectCount) const
 | |
| {
 | |
|   if (inputRectCount != 1) {
 | |
|       return E_INVALIDARG;
 | |
|   }
 | |
| 
 | |
|   *pInputRects = *pOutputRect;
 | |
|   return S_OK;
 | |
| }
 | |
| 
 | |
| IFACEMETHODIMP
 | |
| ExtendInputEffectD2D1::MapInvalidRect(UINT32 inputIndex,
 | |
|                                       D2D1_RECT_L invalidInputRect,
 | |
|                                       D2D1_RECT_L* pInvalidOutputRect) const
 | |
| {
 | |
|   MOZ_ASSERT(inputIndex == 0);
 | |
| 
 | |
|   *pInvalidOutputRect = invalidInputRect;
 | |
|   return S_OK;
 | |
| }
 | |
| 
 | |
| HRESULT
 | |
| ExtendInputEffectD2D1::Register(ID2D1Factory1 *aFactory)
 | |
| {
 | |
|   D2D1_PROPERTY_BINDING bindings[] = {
 | |
|     D2D1_VALUE_TYPE_BINDING(L"OutputRect", &ExtendInputEffectD2D1::SetOutputRect, &ExtendInputEffectD2D1::GetOutputRect),
 | |
|   };
 | |
|   HRESULT hr = aFactory->RegisterEffectFromString(CLSID_ExtendInputEffect, kXmlDescription, bindings, 1, CreateEffect);
 | |
| 
 | |
|   if (FAILED(hr)) {
 | |
|     gfxWarning() << "Failed to register extend input effect.";
 | |
|   }
 | |
|   return hr;
 | |
| }
 | |
| 
 | |
| void
 | |
| ExtendInputEffectD2D1::Unregister(ID2D1Factory1 *aFactory)
 | |
| {
 | |
|   aFactory->UnregisterEffect(CLSID_ExtendInputEffect);
 | |
| }
 | |
| 
 | |
| HRESULT __stdcall
 | |
| ExtendInputEffectD2D1::CreateEffect(IUnknown **aEffectImpl)
 | |
| {
 | |
|   *aEffectImpl = static_cast<ID2D1EffectImpl*>(new ExtendInputEffectD2D1());
 | |
|   (*aEffectImpl)->AddRef();
 | |
| 
 | |
|   return S_OK;
 | |
| }
 | |
| 
 | |
| }
 | |
| }
 |