/// <summary> /// Function to rent a render target from the factory. /// </summary> /// <param name="targetInfo">The information about the render target to retrieve.</param> /// <param name="name">A unique user defined name for a new render target.</param> /// <param name="clearOnRetrieve">[Optional] <b>true</b> to clear the render target when retrieved, or <b>false</b> to leave the contents as-is.</param> /// <returns>The requested render target.</returns> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="targetInfo"/>, or the <paramref name="name"/> parameter is <b>null</b>.</exception> /// <exception cref="ArgumentException">Thrown when the <paramref name="name"/> parameter is empty.</exception> /// <remarks> /// <para> /// All calls to this method should be paired with a call to the <see cref="Return"/> method. Failure to do so may result in a leak. /// </para> /// <para> /// The optional <paramref name="clearOnRetrieve"/> parameter, if set to <b>true</b>,, will clear the contents of a render target that is being reused /// prior to returning it. In some cases this is not ideal, so setting it to <b>false</b> will preserve the contents. New render targets will always /// be cleared. /// </para> /// <note type="caution"> /// <para> /// For performance reasons, any exceptions thrown from this method will only be thrown when Gorgon is compiled as DEBUG. /// </para> /// </note> /// </remarks> public GorgonRenderTarget2DView Rent(IGorgonTexture2DInfo targetInfo, string name, bool clearOnRetrieve = true) { name.ValidateString(nameof(name)); targetInfo.ValidateObject(nameof(targetInfo)); ExpireTargets(); // Ensure the information is valid. GorgonTexture2DInfo newInfo = _textureInfoAllocator.Allocate(); newInfo.Copy(name, targetInfo); newInfo.Binding = targetInfo.Binding | TextureBinding.RenderTarget | TextureBinding.ShaderResource; newInfo.Usage = ResourceUsage.Default; for (int i = 0; i < _renderTargets.Count; ++i) { GorgonRenderTarget2DView rtv = _renderTargets[i]; GorgonTexture2D target = _renderTargets[i].Texture; if ((!_rented.Contains(rtv)) && (target.Width == newInfo.Width) && (target.Height == newInfo.Height) && (target.MipLevels == newInfo.MipLevels) && (target.ArrayCount == newInfo.ArrayCount) && (target.Format == newInfo.Format) && (target.Binding == newInfo.Binding) && (target.MultisampleInfo.Equals(newInfo.MultisampleInfo)) && (newInfo.IsCubeMap == target.IsCubeMap) && (string.Equals(newInfo.Name, rtv.Texture.Name, StringComparison.OrdinalIgnoreCase))) { if (clearOnRetrieve) { rtv.Clear(GorgonColor.BlackTransparent); } _renderTargets.Remove(rtv); _expiryTime.Remove(rtv); _rented.Add(rtv); return(rtv); } } if (_renderTargets.Count == 0) { _expiryTimer.Reset(); } var newRtv = GorgonRenderTarget2DView.CreateRenderTarget(_graphics, newInfo); // Cache a default shader resource view (the texture holds the cache, we hold a separate one so we can clean it up later). _srvs.Add(newRtv.GetShaderResourceView()); newRtv.OwnerFactory = this; _rented.Add(newRtv); newRtv.Clear(GorgonColor.BlackTransparent); return(newRtv); }
/// <summary> /// Function to create a new draw call. /// </summary> /// <param name="allocator">The allocator to use when creating draw call objects.</param> /// <returns>A new draw call.</returns> protected override GorgonInstancedCall OnCreate(GorgonRingPool <GorgonInstancedCall> allocator) => allocator == null ? new GorgonInstancedCall() : allocator.Allocate();
/// <summary> /// Function to create a new draw call. /// </summary> /// <param name="allocator">The allocator to use when creating draw call objects.</param> /// <returns>A new draw call.</returns> protected override GorgonDrawIndexCall OnCreate(GorgonRingPool <GorgonDrawIndexCall> allocator) => allocator == null ? new GorgonDrawIndexCall() : allocator.Allocate();