Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
VertexArrayObject.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using SiliconStudio.Core;
7 using SiliconStudio.Core.Extensions;
8 using SiliconStudio.Core.ReferenceCounting;
9 
10 namespace SiliconStudio.Paradox.Graphics
11 {
12  public partial class VertexArrayObject : GraphicsResourceBase
13  {
14  private readonly IndexBufferBinding indexBufferBinding;
15  private readonly VertexBufferBinding[] vertexBufferBindings;
16  private static readonly VertexBufferBinding[] emptyVertexBufferBindings = new VertexBufferBinding[0];
17  private Description description;
18 
19  public static VertexArrayObject New(GraphicsDevice graphicsDevice, params VertexBufferBinding[] vertexBufferBindings)
20  {
21  return New(graphicsDevice, null, null, vertexBufferBindings);
22  }
23 
24  public static VertexArrayObject New(GraphicsDevice graphicsDevice, IndexBufferBinding indexBufferBinding, params VertexBufferBinding[] vertexBufferBindings)
25  {
26  return New(graphicsDevice, null, indexBufferBinding, vertexBufferBindings);
27  }
28 
29  public static VertexArrayObject New(GraphicsDevice graphicsDevice, EffectInputSignature shaderSignature, params VertexBufferBinding[] vertexBufferBindings)
30  {
31  return New(graphicsDevice, shaderSignature, null, vertexBufferBindings);
32  }
33 
34  public static VertexArrayObject New(GraphicsDevice graphicsDevice, EffectInputSignature shaderSignature, IndexBufferBinding indexBufferBinding, params VertexBufferBinding[] vertexBufferBindings)
35  {
36  // Store SamplerState in a cache (D3D seems to have quite bad concurrency when using CreateSampler while rendering)
37  VertexArrayObject vertexArrayObject;
38  var description = new Description(shaderSignature, vertexBufferBindings, indexBufferBinding);
39 
40  lock (graphicsDevice.CachedVertexArrayObjects)
41  {
42  if (graphicsDevice.CachedVertexArrayObjects.TryGetValue(description, out vertexArrayObject))
43  {
44  // TODO: Appropriate destroy
45  vertexArrayObject.AddReferenceInternal();
46  }
47  else
48  {
49  vertexArrayObject = new VertexArrayObject(graphicsDevice, shaderSignature, indexBufferBinding, vertexBufferBindings);
50 
51  // For now store description as is to avoid having to recreate it on Destroy.
52  // It would probably save little bit of memory space to try to reuse existing fields and add only what's missing.
53  vertexArrayObject.description = description;
54 
55  graphicsDevice.CachedVertexArrayObjects.Add(description, vertexArrayObject);
56  }
57  }
58 
59  return vertexArrayObject;
60  }
61 
62  protected override void Destroy()
63  {
64  lock (GraphicsDevice.CachedVertexArrayObjects)
65  {
66  GraphicsDevice.CachedVertexArrayObjects.Remove(description);
67  }
68 
69  // Release underlying resources
70  foreach (var vertexBufferBinding in vertexBufferBindings)
71  {
72  ((IReferencable)vertexBufferBinding.Buffer).Release();
73  }
74 
75  if (indexBufferBinding != null)
76  {
77  ((IReferencable)indexBufferBinding.Buffer).Release();
78  }
79 
80  base.Destroy();
81  }
82 
83  internal struct Description : IEquatable<Description>
84  {
85  private static EqualityComparer<VertexBufferBinding> VertexBufferBindingComparer = EqualityComparer<VertexBufferBinding>.Default;
86  private int hashCode;
87 
88  public EffectInputSignature ShaderSignature;
89  public VertexBufferBinding[] VertexBuffers;
91 
92  public Description(EffectInputSignature shaderSignature, VertexBufferBinding[] vertexBuffers, IndexBufferBinding indexBuffer)
93  {
94  ShaderSignature = shaderSignature;
95  VertexBuffers = vertexBuffers ?? emptyVertexBufferBindings;
96  IndexBuffer = indexBuffer;
97 
98  // Precompute hash code
99  hashCode = 0;
100  hashCode = ComputeHashCode();
101  }
102 
103  public bool Equals(Description other)
104  {
105  return Equals(ShaderSignature, other.ShaderSignature)
106  && ArrayExtensions.ArraysEqual(VertexBuffers, other.VertexBuffers, VertexBufferBindingComparer)
107  && Equals(IndexBuffer, other.IndexBuffer);
108  }
109 
110  public override bool Equals(object obj)
111  {
112  if (ReferenceEquals(null, obj)) return false;
113  return obj is Description && Equals((Description)obj);
114  }
115 
116  public override int GetHashCode()
117  {
118  return hashCode;
119  }
120 
121  private int ComputeHashCode()
122  {
123  unchecked
124  {
125  int hashCode = (ShaderSignature != null ? ShaderSignature.GetHashCode() : 0);
126  hashCode = (hashCode * 397) ^ VertexBuffers.ComputeHash(VertexBufferBindingComparer);
127  hashCode = (hashCode*397) ^ (IndexBuffer != null ? IndexBuffer.GetHashCode() : 0);
128  return hashCode;
129  }
130  }
131  }
132  }
133 }
Base interface for all referencable objects.
Definition: IReferencable.cs:8
static VertexArrayObject New(GraphicsDevice graphicsDevice, EffectInputSignature shaderSignature, IndexBufferBinding indexBufferBinding, params VertexBufferBinding[] vertexBufferBindings)
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
static VertexArrayObject New(GraphicsDevice graphicsDevice, params VertexBufferBinding[] vertexBufferBindings)
override void Destroy()
Disposes of object resources.
Describes an input signature for an Effect.
static VertexArrayObject New(GraphicsDevice graphicsDevice, EffectInputSignature shaderSignature, params VertexBufferBinding[] vertexBufferBindings)
static VertexArrayObject New(GraphicsDevice graphicsDevice, IndexBufferBinding indexBufferBinding, params VertexBufferBinding[] vertexBufferBindings)
Binding structure that specifies a vertex buffer and other per-vertex parameters (such as offset and ...