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"
19 #include "nsReadableUtils.h"
21 #include "gfxContext.h"
22 #include "gfxPlatform.h"
23 #include "GLContext.h"
25 #include "nsContentUtils.h"
27 #include "nsLayoutUtils.h"
29 #include "CanvasUtils.h"
32 #include "jsfriendapi.h"
34 #include "WebGLTexelConversions.h"
35 #include "WebGLValidateStrings.h"
38 // needed to check if current OS is lower than 10.7
39 #if defined(MOZ_WIDGET_COCOA)
40 # include "nsCocoaFeatures.h"
43 #include "mozilla/DebugOnly.h"
44 #include "mozilla/dom/BindingUtils.h"
45 #include "mozilla/dom/ImageData.h"
46 #include "mozilla/EndianUtils.h"
51 bool WebGLContext::IsTexParamValid(GLenum pname
) const {
53 case LOCAL_GL_TEXTURE_MIN_FILTER
:
54 case LOCAL_GL_TEXTURE_MAG_FILTER
:
55 case LOCAL_GL_TEXTURE_WRAP_S
:
56 case LOCAL_GL_TEXTURE_WRAP_T
:
59 case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT
:
60 return IsExtensionEnabled(
61 WebGLExtensionID::EXT_texture_filter_anisotropic
);
68 //////////////////////////////////////////////////////////////////////////////////////////
71 void WebGLContext::BindTexture(GLenum rawTarget
, WebGLTexture
* newTex
) {
72 FuncScope
funcScope(*this, "bindTexture");
73 if (IsContextLost()) return;
74 funcScope
.mBindFailureGuard
= true;
76 if (newTex
&& !ValidateObject("tex", *newTex
)) return;
78 // Need to check rawTarget first before comparing against newTex->Target() as
79 // newTex->Target() returns a TexTarget, which will assert on invalid value.
80 RefPtr
<WebGLTexture
>* currentTexPtr
= nullptr;
82 case LOCAL_GL_TEXTURE_2D
:
83 currentTexPtr
= &mBound2DTextures
[mActiveTexture
];
86 case LOCAL_GL_TEXTURE_CUBE_MAP
:
87 currentTexPtr
= &mBoundCubeMapTextures
[mActiveTexture
];
90 case LOCAL_GL_TEXTURE_3D
:
91 if (IsWebGL2()) currentTexPtr
= &mBound3DTextures
[mActiveTexture
];
94 case LOCAL_GL_TEXTURE_2D_ARRAY
:
95 if (IsWebGL2()) currentTexPtr
= &mBound2DArrayTextures
[mActiveTexture
];
100 ErrorInvalidEnumInfo("target", rawTarget
);
104 const TexTarget
texTarget(rawTarget
);
106 if (!newTex
->BindTexture(texTarget
)) return;
108 gl
->fBindTexture(texTarget
.get(), 0);
111 *currentTexPtr
= newTex
;
113 funcScope
.mBindFailureGuard
= false;
116 void WebGLContext::GenerateMipmap(GLenum texTarget
) {
117 const FuncScope
funcScope(*this, "generateMipmap");
119 const auto& tex
= GetActiveTex(texTarget
);
121 tex
->GenerateMipmap();
124 Maybe
<double> WebGLContext::GetTexParameter(const WebGLTexture
& tex
,
125 GLenum pname
) const {
126 const FuncScope
funcScope(*this, "getTexParameter");
128 if (!IsTexParamValid(pname
)) {
129 ErrorInvalidEnumInfo("pname", pname
);
133 return tex
.GetTexParameter(pname
);
136 void WebGLContext::TexParameter_base(GLenum texTarget
, GLenum pname
,
137 const FloatOrInt
& param
) {
138 const FuncScope
funcScope(*this, "texParameter");
140 const auto& tex
= GetActiveTex(texTarget
);
142 tex
->TexParameter(texTarget
, pname
, param
);
145 //////////////////////////////////////////////////////////////////////////////////////////
148 WebGLTexture
* WebGLContext::GetActiveTex(const GLenum texTarget
) const {
149 const auto* list
= &mBound2DTextures
;
151 case LOCAL_GL_TEXTURE_2D
:
153 case LOCAL_GL_TEXTURE_CUBE_MAP
:
154 list
= &mBoundCubeMapTextures
;
156 case LOCAL_GL_TEXTURE_3D
:
157 list
= IsWebGL2() ? &mBound3DTextures
: nullptr;
159 case LOCAL_GL_TEXTURE_2D_ARRAY
:
160 list
= IsWebGL2() ? &mBound2DArrayTextures
: nullptr;
166 ErrorInvalidEnumArg("target", texTarget
);
169 const auto& tex
= (*list
)[mActiveTexture
];
171 GenerateError(LOCAL_GL_INVALID_OPERATION
, "No texture bound to %s[%u].",
172 EnumString(texTarget
).c_str(), mActiveTexture
);
178 void WebGLContext::TexStorage(GLenum texTarget
, uint32_t levels
,
179 GLenum internalFormat
, uvec3 size
) const {
180 const FuncScope
funcScope(*this, "texStorage(Multisample)?");
181 if (!IsTexTarget3D(texTarget
)) {
184 const auto tex
= GetActiveTex(texTarget
);
186 tex
->TexStorage(texTarget
, levels
, internalFormat
, size
);
189 void WebGLContext::TexImage(uint32_t level
, GLenum respecFormat
, uvec3 offset
,
190 const webgl::PackingInfo
& pi
,
191 const webgl::TexUnpackBlobDesc
& src
) const {
192 const WebGLContext::FuncScope
funcScope(
193 *this, bool(respecFormat
) ? "texImage" : "texSubImage");
195 const bool isUploadFromPbo
= bool(src
.pboOffset
);
196 const bool isPboBound
= bool(mBoundPixelUnpackBuffer
);
197 if (isUploadFromPbo
!= isPboBound
) {
198 GenerateError(LOCAL_GL_INVALID_OPERATION
,
199 "Tex upload from %s but PIXEL_UNPACK_BUFFER %s bound.",
200 isUploadFromPbo
? "PBO" : "non-PBO",
201 isPboBound
? "was" : "was not");
208 const auto texTarget
= ImageToTexTarget(src
.imageTarget
);
209 const auto tex
= GetActiveTex(texTarget
);
211 tex
->TexImage(level
, respecFormat
, offset
, pi
, src
);
214 void WebGLContext::CompressedTexImage(bool sub
, GLenum imageTarget
,
215 uint32_t level
, GLenum format
,
216 uvec3 offset
, uvec3 size
,
217 const Range
<const uint8_t>& src
,
218 const uint32_t pboImageSize
,
219 const Maybe
<uint64_t>& pboOffset
) const {
220 const WebGLContext::FuncScope
funcScope(
221 *this, !sub
? "compressedTexImage" : "compressedTexSubImage");
226 const auto texTarget
= ImageToTexTarget(imageTarget
);
227 if (!IsTexTarget3D(texTarget
)) {
230 const auto tex
= GetActiveTex(texTarget
);
232 tex
->CompressedTexImage(sub
, imageTarget
, level
, format
, offset
, size
, src
,
233 pboImageSize
, pboOffset
);
236 void WebGLContext::CopyTexImage(GLenum imageTarget
, uint32_t level
,
237 GLenum respecFormat
, uvec3 dstOffset
,
238 const ivec2
& srcOffset
,
239 const uvec2
& size
) const {
240 const WebGLContext::FuncScope
funcScope(
241 *this, bool(respecFormat
) ? "copyTexImage" : "copyTexSubImage");
244 dstOffset
= {0, 0, 0};
246 const auto tex
= GetActiveTex(ImageToTexTarget(imageTarget
));
248 tex
->CopyTexImage(imageTarget
, level
, respecFormat
, dstOffset
, srcOffset
,
252 } // namespace mozilla