Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / dom / canvas / WebGLContextTextures.cpp
blob2bc56f4b05216f1a8bded984137d88dbb59f3317
1 /* -*- Mode: C++; tab-width: 4; 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/. */
6 #include "WebGLContext.h"
7 #include "WebGLContextUtils.h"
8 #include "WebGLBuffer.h"
9 #include "WebGLShader.h"
10 #include "WebGLProgram.h"
11 #include "WebGLFramebuffer.h"
12 #include "WebGLRenderbuffer.h"
13 #include "WebGLTexture.h"
14 #include "WebGLExtensions.h"
15 #include "WebGLVertexArray.h"
17 #include "nsString.h"
18 #include "nsDebug.h"
19 #include "nsReadableUtils.h"
21 #include "gfxContext.h"
22 #include "gfxPlatform.h"
23 #include "GLContext.h"
25 #include "nsContentUtils.h"
26 #include "nsError.h"
27 #include "nsLayoutUtils.h"
29 #include "CanvasUtils.h"
30 #include "gfxUtils.h"
32 #include "jsfriendapi.h"
34 #include "WebGLTexelConversions.h"
35 #include "WebGLValidateStrings.h"
36 #include <algorithm>
38 #include "mozilla/DebugOnly.h"
39 #include "mozilla/dom/BindingUtils.h"
40 #include "mozilla/dom/ImageData.h"
41 #include "mozilla/EndianUtils.h"
43 namespace mozilla {
45 /*virtual*/
46 bool WebGLContext::IsTexParamValid(GLenum pname) const {
47 switch (pname) {
48 case LOCAL_GL_TEXTURE_MIN_FILTER:
49 case LOCAL_GL_TEXTURE_MAG_FILTER:
50 case LOCAL_GL_TEXTURE_WRAP_S:
51 case LOCAL_GL_TEXTURE_WRAP_T:
52 return true;
54 case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
55 return IsExtensionEnabled(
56 WebGLExtensionID::EXT_texture_filter_anisotropic);
58 default:
59 return false;
63 //////////////////////////////////////////////////////////////////////////////////////////
64 // GL calls
66 void WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex) {
67 FuncScope funcScope(*this, "bindTexture");
68 if (IsContextLost()) return;
69 funcScope.mBindFailureGuard = true;
71 if (newTex && !ValidateObject("tex", *newTex)) return;
73 // Need to check rawTarget first before comparing against newTex->Target() as
74 // newTex->Target() returns a TexTarget, which will assert on invalid value.
75 RefPtr<WebGLTexture>* currentTexPtr = nullptr;
76 switch (rawTarget) {
77 case LOCAL_GL_TEXTURE_2D:
78 currentTexPtr = &mBound2DTextures[mActiveTexture];
79 break;
81 case LOCAL_GL_TEXTURE_CUBE_MAP:
82 currentTexPtr = &mBoundCubeMapTextures[mActiveTexture];
83 break;
85 case LOCAL_GL_TEXTURE_3D:
86 if (IsWebGL2()) currentTexPtr = &mBound3DTextures[mActiveTexture];
87 break;
89 case LOCAL_GL_TEXTURE_2D_ARRAY:
90 if (IsWebGL2()) currentTexPtr = &mBound2DArrayTextures[mActiveTexture];
91 break;
94 if (!currentTexPtr) {
95 ErrorInvalidEnumInfo("target", rawTarget);
96 return;
99 const auto texTarget = TexTarget(rawTarget);
100 if (newTex) {
101 if (!newTex->BindTexture(texTarget)) return;
102 } else {
103 gl->fBindTexture(texTarget.get(), 0);
106 *currentTexPtr = newTex;
108 funcScope.mBindFailureGuard = false;
111 void WebGLContext::GenerateMipmap(GLenum texTarget) {
112 const FuncScope funcScope(*this, "generateMipmap");
114 const auto& tex = GetActiveTex(texTarget);
115 if (!tex) return;
116 tex->GenerateMipmap();
119 Maybe<double> WebGLContext::GetTexParameter(const WebGLTexture& tex,
120 GLenum pname) const {
121 const FuncScope funcScope(*this, "getTexParameter");
123 if (!IsTexParamValid(pname)) {
124 ErrorInvalidEnumInfo("pname", pname);
125 return Nothing();
128 return tex.GetTexParameter(pname);
131 void WebGLContext::TexParameter_base(GLenum texTarget, GLenum pname,
132 const FloatOrInt& param) {
133 const FuncScope funcScope(*this, "texParameter");
135 const auto& tex = GetActiveTex(texTarget);
136 if (!tex) return;
137 tex->TexParameter(texTarget, pname, param);
140 //////////////////////////////////////////////////////////////////////////////////////////
141 // Uploads
143 WebGLTexture* WebGLContext::GetActiveTex(const GLenum texTarget) const {
144 const auto* list = &mBound2DTextures;
145 switch (texTarget) {
146 case LOCAL_GL_TEXTURE_2D:
147 break;
148 case LOCAL_GL_TEXTURE_CUBE_MAP:
149 list = &mBoundCubeMapTextures;
150 break;
151 case LOCAL_GL_TEXTURE_3D:
152 list = IsWebGL2() ? &mBound3DTextures : nullptr;
153 break;
154 case LOCAL_GL_TEXTURE_2D_ARRAY:
155 list = IsWebGL2() ? &mBound2DArrayTextures : nullptr;
156 break;
157 default:
158 list = nullptr;
160 if (!list) {
161 ErrorInvalidEnumArg("target", texTarget);
162 return nullptr;
164 const auto& tex = (*list)[mActiveTexture];
165 if (!tex) {
166 GenerateError(LOCAL_GL_INVALID_OPERATION, "No texture bound to %s[%u].",
167 EnumString(texTarget).c_str(), mActiveTexture);
168 return nullptr;
170 return tex;
173 void WebGLContext::TexStorage(GLenum texTarget, uint32_t levels,
174 GLenum internalFormat, uvec3 size) const {
175 const FuncScope funcScope(*this, "texStorage(Multisample)?");
176 if (!IsTexTarget3D(texTarget)) {
177 size.z = 1;
179 const auto tex = GetActiveTex(texTarget);
180 if (!tex) return;
181 tex->TexStorage(texTarget, levels, internalFormat, size);
184 void WebGLContext::TexImage(uint32_t level, GLenum respecFormat, uvec3 offset,
185 const webgl::PackingInfo& pi,
186 const webgl::TexUnpackBlobDesc& src) const {
187 const WebGLContext::FuncScope funcScope(
188 *this, bool(respecFormat) ? "texImage" : "texSubImage");
190 const bool isUploadFromPbo = bool(src.pboOffset);
191 const bool isPboBound = bool(mBoundPixelUnpackBuffer);
192 if (isUploadFromPbo != isPboBound) {
193 GenerateError(LOCAL_GL_INVALID_OPERATION,
194 "Tex upload from %s but PIXEL_UNPACK_BUFFER %s bound.",
195 isUploadFromPbo ? "PBO" : "non-PBO",
196 isPboBound ? "was" : "was not");
197 return;
200 if (respecFormat) {
201 offset = {0, 0, 0};
203 const auto texTarget = ImageToTexTarget(src.imageTarget);
204 const auto tex = GetActiveTex(texTarget);
205 if (!tex) return;
206 tex->TexImage(level, respecFormat, offset, pi, src);
209 void WebGLContext::CompressedTexImage(bool sub, GLenum imageTarget,
210 uint32_t level, GLenum format,
211 uvec3 offset, uvec3 size,
212 const Range<const uint8_t>& src,
213 const uint32_t pboImageSize,
214 const Maybe<uint64_t>& pboOffset) const {
215 const WebGLContext::FuncScope funcScope(
216 *this, !sub ? "compressedTexImage" : "compressedTexSubImage");
218 if (!sub) {
219 offset = {0, 0, 0};
221 const auto texTarget = ImageToTexTarget(imageTarget);
222 if (!IsTexTarget3D(texTarget)) {
223 size.z = 1;
225 const auto tex = GetActiveTex(texTarget);
226 if (!tex) return;
227 tex->CompressedTexImage(sub, imageTarget, level, format, offset, size, src,
228 pboImageSize, pboOffset);
231 void WebGLContext::CopyTexImage(GLenum imageTarget, uint32_t level,
232 GLenum respecFormat, uvec3 dstOffset,
233 const ivec2& srcOffset,
234 const uvec2& size) const {
235 const WebGLContext::FuncScope funcScope(
236 *this, bool(respecFormat) ? "copyTexImage" : "copyTexSubImage");
238 if (respecFormat) {
239 dstOffset = {0, 0, 0};
241 const auto tex = GetActiveTex(ImageToTexTarget(imageTarget));
242 if (!tex) return;
243 tex->CopyTexImage(imageTarget, level, respecFormat, dstOffset, srcOffset,
244 size);
247 } // namespace mozilla