1 | import { SCALE_MODES, FORMATS, ALPHA_MODES, TYPES, MIPMAP_MODES, WRAP_MODES, TARGETS } from '@pixi/constants';
|
2 | import { settings } from '@pixi/settings';
|
3 | import { EventEmitter, uid, isPow2, BaseTextureCache, TextureCache } from '@pixi/utils';
|
4 | import { autoDetectResource } from './resources/autoDetectResource.mjs';
|
5 | import { BufferResource } from './resources/BufferResource.mjs';
|
6 | import { Resource } from './resources/Resource.mjs';
|
7 |
|
8 | const defaultBufferOptions = {
|
9 | scaleMode: SCALE_MODES.NEAREST,
|
10 | format: FORMATS.RGBA,
|
11 | alphaMode: ALPHA_MODES.NPM
|
12 | };
|
13 | const _BaseTexture = class extends EventEmitter {
|
14 | constructor(resource = null, options = null) {
|
15 | super();
|
16 | options = Object.assign({}, _BaseTexture.defaultOptions, options);
|
17 | const {
|
18 | alphaMode,
|
19 | mipmap,
|
20 | anisotropicLevel,
|
21 | scaleMode,
|
22 | width,
|
23 | height,
|
24 | wrapMode,
|
25 | format,
|
26 | type,
|
27 | target,
|
28 | resolution,
|
29 | resourceOptions
|
30 | } = options;
|
31 | if (resource && !(resource instanceof Resource)) {
|
32 | resource = autoDetectResource(resource, resourceOptions);
|
33 | resource.internal = true;
|
34 | }
|
35 | this.resolution = resolution || settings.RESOLUTION;
|
36 | this.width = Math.round((width || 0) * this.resolution) / this.resolution;
|
37 | this.height = Math.round((height || 0) * this.resolution) / this.resolution;
|
38 | this._mipmap = mipmap;
|
39 | this.anisotropicLevel = anisotropicLevel;
|
40 | this._wrapMode = wrapMode;
|
41 | this._scaleMode = scaleMode;
|
42 | this.format = format;
|
43 | this.type = type;
|
44 | this.target = target;
|
45 | this.alphaMode = alphaMode;
|
46 | this.uid = uid();
|
47 | this.touched = 0;
|
48 | this.isPowerOfTwo = false;
|
49 | this._refreshPOT();
|
50 | this._glTextures = {};
|
51 | this.dirtyId = 0;
|
52 | this.dirtyStyleId = 0;
|
53 | this.cacheId = null;
|
54 | this.valid = width > 0 && height > 0;
|
55 | this.textureCacheIds = [];
|
56 | this.destroyed = false;
|
57 | this.resource = null;
|
58 | this._batchEnabled = 0;
|
59 | this._batchLocation = 0;
|
60 | this.parentTextureArray = null;
|
61 | this.setResource(resource);
|
62 | }
|
63 | get realWidth() {
|
64 | return Math.round(this.width * this.resolution);
|
65 | }
|
66 | get realHeight() {
|
67 | return Math.round(this.height * this.resolution);
|
68 | }
|
69 | get mipmap() {
|
70 | return this._mipmap;
|
71 | }
|
72 | set mipmap(value) {
|
73 | if (this._mipmap !== value) {
|
74 | this._mipmap = value;
|
75 | this.dirtyStyleId++;
|
76 | }
|
77 | }
|
78 | get scaleMode() {
|
79 | return this._scaleMode;
|
80 | }
|
81 | set scaleMode(value) {
|
82 | if (this._scaleMode !== value) {
|
83 | this._scaleMode = value;
|
84 | this.dirtyStyleId++;
|
85 | }
|
86 | }
|
87 | get wrapMode() {
|
88 | return this._wrapMode;
|
89 | }
|
90 | set wrapMode(value) {
|
91 | if (this._wrapMode !== value) {
|
92 | this._wrapMode = value;
|
93 | this.dirtyStyleId++;
|
94 | }
|
95 | }
|
96 | setStyle(scaleMode, mipmap) {
|
97 | let dirty;
|
98 | if (scaleMode !== void 0 && scaleMode !== this.scaleMode) {
|
99 | this.scaleMode = scaleMode;
|
100 | dirty = true;
|
101 | }
|
102 | if (mipmap !== void 0 && mipmap !== this.mipmap) {
|
103 | this.mipmap = mipmap;
|
104 | dirty = true;
|
105 | }
|
106 | if (dirty) {
|
107 | this.dirtyStyleId++;
|
108 | }
|
109 | return this;
|
110 | }
|
111 | setSize(desiredWidth, desiredHeight, resolution) {
|
112 | resolution = resolution || this.resolution;
|
113 | return this.setRealSize(desiredWidth * resolution, desiredHeight * resolution, resolution);
|
114 | }
|
115 | setRealSize(realWidth, realHeight, resolution) {
|
116 | this.resolution = resolution || this.resolution;
|
117 | this.width = Math.round(realWidth) / this.resolution;
|
118 | this.height = Math.round(realHeight) / this.resolution;
|
119 | this._refreshPOT();
|
120 | this.update();
|
121 | return this;
|
122 | }
|
123 | _refreshPOT() {
|
124 | this.isPowerOfTwo = isPow2(this.realWidth) && isPow2(this.realHeight);
|
125 | }
|
126 | setResolution(resolution) {
|
127 | const oldResolution = this.resolution;
|
128 | if (oldResolution === resolution) {
|
129 | return this;
|
130 | }
|
131 | this.resolution = resolution;
|
132 | if (this.valid) {
|
133 | this.width = Math.round(this.width * oldResolution) / resolution;
|
134 | this.height = Math.round(this.height * oldResolution) / resolution;
|
135 | this.emit("update", this);
|
136 | }
|
137 | this._refreshPOT();
|
138 | return this;
|
139 | }
|
140 | setResource(resource) {
|
141 | if (this.resource === resource) {
|
142 | return this;
|
143 | }
|
144 | if (this.resource) {
|
145 | throw new Error("Resource can be set only once");
|
146 | }
|
147 | resource.bind(this);
|
148 | this.resource = resource;
|
149 | return this;
|
150 | }
|
151 | update() {
|
152 | if (!this.valid) {
|
153 | if (this.width > 0 && this.height > 0) {
|
154 | this.valid = true;
|
155 | this.emit("loaded", this);
|
156 | this.emit("update", this);
|
157 | }
|
158 | } else {
|
159 | this.dirtyId++;
|
160 | this.dirtyStyleId++;
|
161 | this.emit("update", this);
|
162 | }
|
163 | }
|
164 | onError(event) {
|
165 | this.emit("error", this, event);
|
166 | }
|
167 | destroy() {
|
168 | if (this.resource) {
|
169 | this.resource.unbind(this);
|
170 | if (this.resource.internal) {
|
171 | this.resource.destroy();
|
172 | }
|
173 | this.resource = null;
|
174 | }
|
175 | if (this.cacheId) {
|
176 | delete BaseTextureCache[this.cacheId];
|
177 | delete TextureCache[this.cacheId];
|
178 | this.cacheId = null;
|
179 | }
|
180 | this.dispose();
|
181 | _BaseTexture.removeFromCache(this);
|
182 | this.textureCacheIds = null;
|
183 | this.destroyed = true;
|
184 | }
|
185 | dispose() {
|
186 | this.emit("dispose", this);
|
187 | }
|
188 | castToBaseTexture() {
|
189 | return this;
|
190 | }
|
191 | static from(source, options, strict = settings.STRICT_TEXTURE_CACHE) {
|
192 | const isFrame = typeof source === "string";
|
193 | let cacheId = null;
|
194 | if (isFrame) {
|
195 | cacheId = source;
|
196 | } else {
|
197 | if (!source._pixiId) {
|
198 | const prefix = options?.pixiIdPrefix || "pixiid";
|
199 | source._pixiId = `${prefix}_${uid()}`;
|
200 | }
|
201 | cacheId = source._pixiId;
|
202 | }
|
203 | let baseTexture = BaseTextureCache[cacheId];
|
204 | if (isFrame && strict && !baseTexture) {
|
205 | throw new Error(`The cacheId "${cacheId}" does not exist in BaseTextureCache.`);
|
206 | }
|
207 | if (!baseTexture) {
|
208 | baseTexture = new _BaseTexture(source, options);
|
209 | baseTexture.cacheId = cacheId;
|
210 | _BaseTexture.addToCache(baseTexture, cacheId);
|
211 | }
|
212 | return baseTexture;
|
213 | }
|
214 | static fromBuffer(buffer, width, height, options) {
|
215 | buffer = buffer || new Float32Array(width * height * 4);
|
216 | const resource = new BufferResource(buffer, { width, height });
|
217 | const type = buffer instanceof Float32Array ? TYPES.FLOAT : TYPES.UNSIGNED_BYTE;
|
218 | return new _BaseTexture(resource, Object.assign({}, defaultBufferOptions, options || { width, height, type }));
|
219 | }
|
220 | static addToCache(baseTexture, id) {
|
221 | if (id) {
|
222 | if (!baseTexture.textureCacheIds.includes(id)) {
|
223 | baseTexture.textureCacheIds.push(id);
|
224 | }
|
225 | if (BaseTextureCache[id] && BaseTextureCache[id] !== baseTexture) {
|
226 | console.warn(`BaseTexture added to the cache with an id [${id}] that already had an entry`);
|
227 | }
|
228 | BaseTextureCache[id] = baseTexture;
|
229 | }
|
230 | }
|
231 | static removeFromCache(baseTexture) {
|
232 | if (typeof baseTexture === "string") {
|
233 | const baseTextureFromCache = BaseTextureCache[baseTexture];
|
234 | if (baseTextureFromCache) {
|
235 | const index = baseTextureFromCache.textureCacheIds.indexOf(baseTexture);
|
236 | if (index > -1) {
|
237 | baseTextureFromCache.textureCacheIds.splice(index, 1);
|
238 | }
|
239 | delete BaseTextureCache[baseTexture];
|
240 | return baseTextureFromCache;
|
241 | }
|
242 | } else if (baseTexture?.textureCacheIds) {
|
243 | for (let i = 0; i < baseTexture.textureCacheIds.length; ++i) {
|
244 | delete BaseTextureCache[baseTexture.textureCacheIds[i]];
|
245 | }
|
246 | baseTexture.textureCacheIds.length = 0;
|
247 | return baseTexture;
|
248 | }
|
249 | return null;
|
250 | }
|
251 | };
|
252 | let BaseTexture = _BaseTexture;
|
253 | BaseTexture.defaultOptions = {
|
254 | mipmap: MIPMAP_MODES.POW2,
|
255 | anisotropicLevel: 0,
|
256 | scaleMode: SCALE_MODES.LINEAR,
|
257 | wrapMode: WRAP_MODES.CLAMP,
|
258 | alphaMode: ALPHA_MODES.UNPACK,
|
259 | target: TARGETS.TEXTURE_2D,
|
260 | format: FORMATS.RGBA,
|
261 | type: TYPES.UNSIGNED_BYTE
|
262 | };
|
263 | BaseTexture._globalBatch = 0;
|
264 |
|
265 | export { BaseTexture };
|
266 |
|