1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "WebGLSampler.h"
7 
8 #include "GLContext.h"
9 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
10 #include "WebGLContext.h"
11 
12 namespace mozilla {
13 
WebGLSampler(WebGLContext * const webgl)14 WebGLSampler::WebGLSampler(WebGLContext* const webgl)
15     : WebGLContextBoundObject(webgl), mGLName([&]() {
16         GLuint ret = 0;
17         webgl->gl->fGenSamplers(1, &ret);
18         return ret;
19       }()) {}
20 
~WebGLSampler()21 WebGLSampler::~WebGLSampler() {
22   if (!mContext) return;
23   mContext->gl->fDeleteSamplers(1, &mGLName);
24 }
25 
ValidateSamplerParameterParams(WebGLContext * webgl,GLenum pname,const FloatOrInt & param)26 static bool ValidateSamplerParameterParams(WebGLContext* webgl, GLenum pname,
27                                            const FloatOrInt& param) {
28   const auto& paramInt = param.i;
29   bool pnameValid = true;
30   switch (pname) {
31     case LOCAL_GL_TEXTURE_MIN_FILTER:
32       switch (paramInt) {
33         case LOCAL_GL_NEAREST:
34         case LOCAL_GL_LINEAR:
35         case LOCAL_GL_NEAREST_MIPMAP_NEAREST:
36         case LOCAL_GL_NEAREST_MIPMAP_LINEAR:
37         case LOCAL_GL_LINEAR_MIPMAP_NEAREST:
38         case LOCAL_GL_LINEAR_MIPMAP_LINEAR:
39           return true;
40 
41         default:
42           break;
43       }
44       break;
45 
46     case LOCAL_GL_TEXTURE_MAG_FILTER:
47       switch (paramInt) {
48         case LOCAL_GL_NEAREST:
49         case LOCAL_GL_LINEAR:
50           return true;
51 
52         default:
53           break;
54       }
55       break;
56 
57     case LOCAL_GL_TEXTURE_WRAP_S:
58     case LOCAL_GL_TEXTURE_WRAP_T:
59     case LOCAL_GL_TEXTURE_WRAP_R:
60       switch (paramInt) {
61         case LOCAL_GL_CLAMP_TO_EDGE:
62         case LOCAL_GL_REPEAT:
63         case LOCAL_GL_MIRRORED_REPEAT:
64           return true;
65 
66         default:
67           break;
68       }
69       break;
70 
71     case LOCAL_GL_TEXTURE_MIN_LOD:
72     case LOCAL_GL_TEXTURE_MAX_LOD:
73       return true;
74 
75     case LOCAL_GL_TEXTURE_COMPARE_MODE:
76       switch (paramInt) {
77         case LOCAL_GL_NONE:
78         case LOCAL_GL_COMPARE_REF_TO_TEXTURE:
79           return true;
80 
81         default:
82           break;
83       }
84       break;
85 
86     case LOCAL_GL_TEXTURE_COMPARE_FUNC:
87       switch (paramInt) {
88         case LOCAL_GL_LEQUAL:
89         case LOCAL_GL_GEQUAL:
90         case LOCAL_GL_LESS:
91         case LOCAL_GL_GREATER:
92         case LOCAL_GL_EQUAL:
93         case LOCAL_GL_NOTEQUAL:
94         case LOCAL_GL_ALWAYS:
95         case LOCAL_GL_NEVER:
96           return true;
97 
98         default:
99           break;
100       }
101       break;
102 
103     case LOCAL_GL_TEXTURE_MAX_ANISOTROPY:
104       if (webgl->IsExtensionEnabled(
105               WebGLExtensionID::EXT_texture_filter_anisotropic)) {
106         return true;
107       }
108       pnameValid = false;
109       break;
110 
111     default:
112       pnameValid = false;
113       break;
114   }
115 
116   if (!pnameValid) {
117     webgl->ErrorInvalidEnumInfo("pname", pname);
118     return false;
119   }
120 
121   webgl->ErrorInvalidEnumInfo("param", paramInt);
122   return false;
123 }
124 
SamplerParameter(GLenum pname,const FloatOrInt & param)125 void WebGLSampler::SamplerParameter(GLenum pname, const FloatOrInt& param) {
126   if (!ValidateSamplerParameterParams(mContext, pname, param)) return;
127 
128   bool invalidate = true;
129   switch (pname) {
130     case LOCAL_GL_TEXTURE_MIN_FILTER:
131       mState.minFilter = param.i;
132       break;
133 
134     case LOCAL_GL_TEXTURE_MAG_FILTER:
135       mState.magFilter = param.i;
136       break;
137 
138     case LOCAL_GL_TEXTURE_WRAP_S:
139       mState.wrapS = param.i;
140       break;
141 
142     case LOCAL_GL_TEXTURE_WRAP_T:
143       mState.wrapT = param.i;
144       break;
145 
146     case LOCAL_GL_TEXTURE_COMPARE_MODE:
147       mState.compareMode = param.i;
148       break;
149 
150     default:
151       invalidate = false;
152       break;
153   }
154 
155   if (invalidate) {
156     InvalidateCaches();
157   }
158 
159   ////
160 
161   if (param.isFloat) {
162     mContext->gl->fSamplerParameterf(mGLName, pname, param.f);
163   } else {
164     mContext->gl->fSamplerParameteri(mGLName, pname, param.i);
165   }
166 }
167 
168 }  // namespace mozilla
169