WebViewTextureResource.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. // Copyright Epic Games, Inc. All Rights Reserved.
  2. #include "WebViewTextureResource.h"
  3. #include "DeviceProfiles/DeviceProfile.h"
  4. #include "DeviceProfiles/DeviceProfileManager.h"
  5. #include "ExternalTexture.h"
  6. #include "PipelineStateCache.h"
  7. #include "SceneUtils.h"
  8. #include "Shader.h"
  9. #include "StaticBoundShaderState.h"
  10. #include "RenderUtils.h"
  11. #include "RHIStaticStates.h"
  12. #include "ExternalTexture.h"
  13. #include "CoreWebLog.h"
  14. #include "WebViewTexture.h"
  15. #define WebViewTextureRESOURCE_TRACE_RENDER 0
  16. /* FWebViewTextureResource structors
  17. *****************************************************************************/
  18. FWebViewTextureResource::FWebViewTextureResource(UWebViewTexture& InOwner, FIntPoint& InOwnerDim, SIZE_T& InOwnerSize)
  19. : Cleared(false)
  20. , CurrentClearColor(FLinearColor::Transparent)
  21. , Owner(InOwner)
  22. , OwnerDim(InOwnerDim)
  23. , OwnerSize(InOwnerSize)
  24. {
  25. UE_LOG(WebViewLog, VeryVerbose, TEXT("FWebViewTextureResource:FWebViewTextureResource %d %d"), OwnerDim.X, OwnerDim.Y);
  26. }
  27. /* FWebViewTextureResource interface
  28. *****************************************************************************/
  29. void FWebViewTextureResource::Render(const FRenderParams& Params)
  30. {
  31. check(IsInRenderingThread());
  32. TSharedPtr<FWebViewTextureSampleQueue, ESPMode::ThreadSafe> SampleSource = Params.SampleSource.Pin();
  33. if (SampleSource.IsValid())
  34. {
  35. // get the most current sample to be rendered
  36. TSharedPtr<FWebViewTextureSample, ESPMode::ThreadSafe> Sample;
  37. bool SampleValid = false;
  38. while (SampleSource->Peek(Sample) && Sample.IsValid())
  39. {
  40. SampleValid = SampleSource->Dequeue(Sample);
  41. }
  42. if (!SampleValid)
  43. {
  44. return; // no sample to render
  45. }
  46. check(Sample.IsValid());
  47. // render the sample
  48. CopySample(Sample, Params.ClearColor);
  49. if (!GSupportsImageExternal && Params.PlayerGuid.IsValid())
  50. {
  51. FTextureRHIRef VideoTexture = (FTextureRHIRef)Owner.TextureReference.TextureReferenceRHI;
  52. FExternalTextureRegistry::Get().RegisterExternalTexture(Params.PlayerGuid, VideoTexture, SamplerStateRHI, Sample->GetScaleRotation(), Sample->GetOffset());
  53. }
  54. }
  55. else if (!Cleared)
  56. {
  57. ClearTexture(Params.ClearColor);
  58. if (!GSupportsImageExternal && Params.PlayerGuid.IsValid())
  59. {
  60. FTextureRHIRef VideoTexture = (FTextureRHIRef)Owner.TextureReference.TextureReferenceRHI;
  61. FExternalTextureRegistry::Get().RegisterExternalTexture(Params.PlayerGuid, VideoTexture, SamplerStateRHI, FLinearColor(1.0f, 0.0f, 0.0f, 1.0f), FLinearColor(0.0f, 0.0f, 0.0f, 0.0f));
  62. }
  63. }
  64. }
  65. /* FRenderTarget interface
  66. *****************************************************************************/
  67. FIntPoint FWebViewTextureResource::GetSizeXY() const
  68. {
  69. return FIntPoint(Owner.GetWidth(), Owner.GetHeight());
  70. }
  71. /* FTextureResource interface
  72. *****************************************************************************/
  73. FString FWebViewTextureResource::GetFriendlyName() const
  74. {
  75. return Owner.GetPathName();
  76. }
  77. uint32 FWebViewTextureResource::GetSizeX() const
  78. {
  79. return Owner.GetWidth();
  80. }
  81. uint32 FWebViewTextureResource::GetSizeY() const
  82. {
  83. return Owner.GetHeight();
  84. }
  85. #if WEBVIEW_ENGINE_VERSION >= 50300
  86. void FWebViewTextureResource::InitRHI(FRHICommandListBase& RHICmdList )
  87. {
  88. // create the sampler state
  89. FSamplerStateInitializerRHI SamplerStateInitializer(
  90. (ESamplerFilter)UDeviceProfileManager::Get().GetActiveProfile()->GetTextureLODSettings()->GetSamplerFilter(&Owner),
  91. (Owner.AddressX == TA_Wrap) ? AM_Wrap : ((Owner.AddressX == TA_Clamp) ? AM_Clamp : AM_Mirror),
  92. (Owner.AddressY == TA_Wrap) ? AM_Wrap : ((Owner.AddressY == TA_Clamp) ? AM_Clamp : AM_Mirror),
  93. AM_Wrap
  94. );
  95. SamplerStateRHI = RHICreateSamplerState(SamplerStateInitializer);
  96. }
  97. #else
  98. void FWebViewTextureResource::InitDynamicRHI()
  99. {
  100. // create the sampler state
  101. FSamplerStateInitializerRHI SamplerStateInitializer(
  102. (ESamplerFilter)UDeviceProfileManager::Get().GetActiveProfile()->GetTextureLODSettings()->GetSamplerFilter(&Owner),
  103. (Owner.AddressX == TA_Wrap) ? AM_Wrap : ((Owner.AddressX == TA_Clamp) ? AM_Clamp : AM_Mirror),
  104. (Owner.AddressY == TA_Wrap) ? AM_Wrap : ((Owner.AddressY == TA_Clamp) ? AM_Clamp : AM_Mirror),
  105. AM_Wrap
  106. );
  107. SamplerStateRHI = RHICreateSamplerState(SamplerStateInitializer);
  108. }
  109. #endif
  110. void FWebViewTextureResource::ReleaseRHI()
  111. {
  112. Cleared = false;
  113. InputTarget.SafeRelease();
  114. OutputTarget.SafeRelease();
  115. RenderTargetTextureRHI.SafeRelease();
  116. TextureRHI.SafeRelease();
  117. UpdateTextureReference(nullptr);
  118. }
  119. /* FWebViewTextureResource implementation
  120. *****************************************************************************/
  121. void FWebViewTextureResource::ClearTexture(const FLinearColor& ClearColor)
  122. {
  123. UE_LOG(WebViewLog, VeryVerbose, TEXT("FWebViewTextureResource:ClearTexture"));
  124. #if WEBVIEW_ENGINE_VERSION>=50100
  125. // create output render target if we don't have one yet
  126. const ETextureCreateFlags OutputCreateFlags = ETextureCreateFlags::Dynamic | ETextureCreateFlags::SRGB;
  127. if ((ClearColor != CurrentClearColor) || !OutputTarget.IsValid() || !EnumHasAllFlags(OutputTarget->GetFlags(), OutputCreateFlags))
  128. {
  129. const FRHITextureCreateDesc Desc =
  130. FRHITextureCreateDesc::Create2D(TEXT("FWebViewTextureResource"))
  131. .SetExtent(2, 2)
  132. .SetFormat(PF_B8G8R8A8)
  133. .SetFlags(OutputCreateFlags | ETextureCreateFlags::RenderTargetable | ETextureCreateFlags::ShaderResource)
  134. .SetInitialState(ERHIAccess::SRVMask)
  135. .SetClearValue(FClearValueBinding(ClearColor));
  136. OutputTarget = RHICreateTexture(Desc);
  137. CurrentClearColor = ClearColor;
  138. UpdateResourceSize();
  139. }
  140. if (RenderTargetTextureRHI != OutputTarget)
  141. {
  142. UpdateTextureReference(OutputTarget);
  143. }
  144. // draw the clear color
  145. FRHICommandListImmediate& CommandList = FRHICommandListExecutor::GetImmediateCommandList();
  146. {
  147. CommandList.Transition(FRHITransitionInfo(RenderTargetTextureRHI, ERHIAccess::Unknown, ERHIAccess::RTV));
  148. ClearRenderTarget(CommandList, RenderTargetTextureRHI);
  149. CommandList.Transition(FRHITransitionInfo(RenderTargetTextureRHI, ERHIAccess::RTV, ERHIAccess::SRVMask));
  150. }
  151. Cleared = true;
  152. #else
  153. FPlatformMisc::LowLevelOutputDebugStringf(TEXT("FWebBViewTextureResource:ClearTexture"));
  154. // create output render target if we don't have one yet
  155. const ETextureCreateFlags OutputCreateFlags = TexCreate_Dynamic | TexCreate_SRGB;
  156. if ((ClearColor != CurrentClearColor) || !OutputTarget.IsValid() || ((OutputTarget->GetFlags() & OutputCreateFlags) != OutputCreateFlags))
  157. {
  158. #if WEBVIEW_ENGINE_VERSION>=50000
  159. FRHIResourceCreateInfo CreateInfo(TEXT("FWebViewTextureResource"), FClearValueBinding(ClearColor));
  160. #else
  161. FRHIResourceCreateInfo CreateInfo = {
  162. FClearValueBinding(ClearColor)
  163. };
  164. #endif
  165. TRefCountPtr<FRHITexture2D> DummyTexture2DRHI;
  166. RHICreateTargetableShaderResource2D(
  167. 2,
  168. 2,
  169. PF_B8G8R8A8,
  170. 1,
  171. OutputCreateFlags,
  172. TexCreate_RenderTargetable,
  173. false,
  174. CreateInfo,
  175. OutputTarget,
  176. DummyTexture2DRHI
  177. );
  178. CurrentClearColor = ClearColor;
  179. UpdateResourceSize();
  180. }
  181. if (RenderTargetTextureRHI != OutputTarget)
  182. {
  183. UpdateTextureReference(OutputTarget);
  184. }
  185. // draw the clear color
  186. FRHICommandListImmediate& CommandList = FRHICommandListExecutor::GetImmediateCommandList();
  187. {
  188. FRHIRenderPassInfo RPInfo(RenderTargetTextureRHI, ERenderTargetActions::Clear_Store);
  189. CommandList.BeginRenderPass(RPInfo, TEXT("ClearTexture"));
  190. CommandList.EndRenderPass();
  191. CommandList.Transition(FRHITransitionInfo(RenderTargetTextureRHI, ERHIAccess::RTV, ERHIAccess::SRVMask));
  192. }
  193. Cleared = true;
  194. #endif
  195. }
  196. void FWebViewTextureResource::CopySample(const TSharedPtr<FWebViewTextureSample, ESPMode::ThreadSafe>& Sample, const FLinearColor& ClearColor)
  197. {
  198. FRHITexture* SampleTexture = Sample->GetTexture();
  199. FRHITexture2D* SampleTexture2D = (SampleTexture != nullptr) ? SampleTexture->GetTexture2D() : nullptr;
  200. // If the sample already provides a texture resource, we simply use that
  201. // as the output render target. If the sample only provides raw data, then
  202. // we create our own output render target and copy the data into it.
  203. if (SampleTexture2D != nullptr)
  204. {
  205. UE_LOG(WebViewLog, VeryVerbose, TEXT("FWebViewTextureResource:CopySample 1"));
  206. // use sample's texture as the new render target.
  207. if (TextureRHI != SampleTexture2D)
  208. {
  209. UE_LOG(WebViewLog, VeryVerbose, TEXT("FWebViewTextureResource:CopySample 11"));
  210. UpdateTextureReference(SampleTexture2D);
  211. OutputTarget.SafeRelease();
  212. UpdateResourceSize();
  213. }
  214. }
  215. else
  216. {
  217. UE_LOG(WebViewLog, VeryVerbose, TEXT("FWebViewTextureResource:CopySample 2"));
  218. // create a new output render target if necessary
  219. const ETextureCreateFlags OutputCreateFlags = TexCreate_Dynamic | TexCreate_SRGB;
  220. const FIntPoint SampleDim = Sample->GetDim();
  221. if ((ClearColor != CurrentClearColor) || !OutputTarget.IsValid() || (OutputTarget->GetSizeXY() != SampleDim) || ((OutputTarget->GetFlags() & OutputCreateFlags) != OutputCreateFlags))
  222. {
  223. UE_LOG(WebViewLog, VeryVerbose, TEXT("FWebViewTextureResource:CopySample 1"));
  224. #if WEBVIEW_ENGINE_VERSION>=50100
  225. const FRHITextureCreateDesc Desc =
  226. FRHITextureCreateDesc::Create2D(TEXT("FWebViewTextureResource"))
  227. .SetExtent(SampleDim)
  228. .SetFormat(PF_B8G8R8A8)
  229. .SetFlags(OutputCreateFlags | ETextureCreateFlags::RenderTargetable | ETextureCreateFlags::ShaderResource)
  230. .SetInitialState(ERHIAccess::SRVMask)
  231. .SetClearValue(FClearValueBinding(ClearColor));
  232. OutputTarget = RHICreateTexture(Desc);
  233. #else
  234. FPlatformMisc::LowLevelOutputDebugStringf(TEXT("FWebBrowserTextureResource:CopySample 1"));
  235. TRefCountPtr<FRHITexture2D> DummyTexture2DRHI;
  236. #if WEBVIEW_ENGINE_VERSION>=50000
  237. FRHIResourceCreateInfo CreateInfo(TEXT("FWebViewTextureResource"), FClearValueBinding(ClearColor));
  238. #else
  239. FRHIResourceCreateInfo CreateInfo = {
  240. FClearValueBinding(ClearColor)
  241. };
  242. #endif
  243. RHICreateTargetableShaderResource2D(
  244. SampleDim.X,
  245. SampleDim.Y,
  246. PF_B8G8R8A8,
  247. 1,
  248. OutputCreateFlags,
  249. TexCreate_RenderTargetable,
  250. false,
  251. CreateInfo,
  252. OutputTarget,
  253. DummyTexture2DRHI
  254. );
  255. #endif
  256. CurrentClearColor = ClearColor;
  257. UpdateResourceSize();
  258. }
  259. if (RenderTargetTextureRHI != OutputTarget)
  260. {
  261. UpdateTextureReference(OutputTarget);
  262. }
  263. UE_LOG(WebViewLog, VeryVerbose, TEXT("WebViewTextureResource:CopySample: %d x %d"), SampleDim.X, SampleDim.Y);
  264. // copy sample data to output render target
  265. FUpdateTextureRegion2D Region(0, 0, 0, 0, SampleDim.X, SampleDim.Y);
  266. RHIUpdateTexture2D(RenderTargetTextureRHI.GetReference(), 0, Region, Sample->GetStride(), (uint8*)Sample->GetBuffer());
  267. }
  268. Cleared = false;
  269. }
  270. void FWebViewTextureResource::UpdateResourceSize()
  271. {
  272. UE_LOG(WebViewLog, VeryVerbose, TEXT("FWebViewTextureResource:UpdateResourceSize"));
  273. SIZE_T ResourceSize = 0;
  274. if (InputTarget.IsValid())
  275. {
  276. ResourceSize += CalcTextureSize(InputTarget->GetSizeX(), InputTarget->GetSizeY(), InputTarget->GetFormat(), 1);
  277. }
  278. if (OutputTarget.IsValid())
  279. {
  280. ResourceSize += CalcTextureSize(OutputTarget->GetSizeX(), OutputTarget->GetSizeY(), OutputTarget->GetFormat(), 1);
  281. }
  282. OwnerSize = ResourceSize;
  283. }
  284. void FWebViewTextureResource::UpdateTextureReference(FRHITexture2D* NewTexture)
  285. {
  286. TextureRHI = NewTexture;
  287. RenderTargetTextureRHI = NewTexture;
  288. RHIUpdateTextureReference(Owner.TextureReference.TextureReferenceRHI, NewTexture);
  289. if (RenderTargetTextureRHI != nullptr)
  290. {
  291. OwnerDim = FIntPoint(RenderTargetTextureRHI->GetSizeX(), RenderTargetTextureRHI->GetSizeY());
  292. }
  293. else
  294. {
  295. OwnerDim = FIntPoint::ZeroValue;
  296. }
  297. UE_LOG(WebViewLog, VeryVerbose, TEXT("FWebViewTextureResource:UpdateTextureReference: %d x %d"), OwnerDim.X, OwnerDim.Y);
  298. }