|
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 #ifndef MOZILLA_GFX_TEXTUREOGL_H |
|
7 #define MOZILLA_GFX_TEXTUREOGL_H |
|
8 |
|
9 #include <stddef.h> // for size_t |
|
10 #include <stdint.h> // for uint64_t |
|
11 #include "CompositableHost.h" |
|
12 #include "GLContextTypes.h" // for GLContext |
|
13 #include "GLDefs.h" // for GLenum, LOCAL_GL_CLAMP_TO_EDGE, etc |
|
14 #include "GLTextureImage.h" // for TextureImage |
|
15 #include "gfxTypes.h" |
|
16 #include "mozilla/GfxMessageUtils.h" // for gfxContentType |
|
17 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
|
18 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE |
|
19 #include "mozilla/RefPtr.h" // for RefPtr |
|
20 #include "mozilla/gfx/Matrix.h" // for Matrix4x4 |
|
21 #include "mozilla/gfx/Point.h" // for IntSize, IntPoint |
|
22 #include "mozilla/gfx/Types.h" // for SurfaceFormat, etc |
|
23 #include "mozilla/layers/CompositorTypes.h" // for TextureFlags |
|
24 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor |
|
25 #include "mozilla/layers/TextureHost.h" // for TextureHost, etc |
|
26 #include "mozilla/mozalloc.h" // for operator delete, etc |
|
27 #include "nsAutoPtr.h" // for nsRefPtr |
|
28 #include "nsCOMPtr.h" // for already_AddRefed |
|
29 #include "nsDebug.h" // for NS_WARNING |
|
30 #include "nsISupportsImpl.h" // for TextureImage::Release, etc |
|
31 #include "OGLShaderProgram.h" // for ShaderProgramType, etc |
|
32 #ifdef MOZ_WIDGET_GONK |
|
33 #include <ui/GraphicBuffer.h> |
|
34 #if ANDROID_VERSION >= 17 |
|
35 #include <ui/Fence.h> |
|
36 #endif |
|
37 #endif |
|
38 |
|
39 class gfxReusableSurfaceWrapper; |
|
40 class nsIntRegion; |
|
41 struct nsIntPoint; |
|
42 struct nsIntRect; |
|
43 struct nsIntSize; |
|
44 |
|
45 namespace mozilla { |
|
46 namespace gfx { |
|
47 class DataSourceSurface; |
|
48 class SurfaceStream; |
|
49 } |
|
50 |
|
51 namespace layers { |
|
52 |
|
53 class Compositor; |
|
54 class CompositorOGL; |
|
55 class TextureImageTextureSourceOGL; |
|
56 |
|
57 /** |
|
58 * CompositableBackendSpecificData implementation for the Gonk OpenGL backend. |
|
59 * Share a same texture between TextureHosts in the same CompositableHost. |
|
60 * By shareing the texture among the TextureHosts, number of texture allocations |
|
61 * can be reduced than texture allocation in every TextureHosts. |
|
62 * From Bug 912134, use only one texture among all TextureHosts degrade |
|
63 * the rendering performance. |
|
64 * CompositableDataGonkOGL chooses in a middile of them. |
|
65 */ |
|
66 class CompositableDataGonkOGL : public CompositableBackendSpecificData |
|
67 { |
|
68 public: |
|
69 CompositableDataGonkOGL(); |
|
70 virtual ~CompositableDataGonkOGL(); |
|
71 |
|
72 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
73 virtual void ClearData() MOZ_OVERRIDE; |
|
74 GLuint GetTexture(); |
|
75 void DeleteTextureIfPresent(); |
|
76 gl::GLContext* gl() const; |
|
77 protected: |
|
78 RefPtr<CompositorOGL> mCompositor; |
|
79 GLuint mTexture; |
|
80 }; |
|
81 |
|
82 inline void ApplyFilterToBoundTexture(gl::GLContext* aGL, |
|
83 gfx::Filter aFilter, |
|
84 GLuint aTarget = LOCAL_GL_TEXTURE_2D) |
|
85 { |
|
86 GLenum filter = |
|
87 (aFilter == gfx::Filter::POINT ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR); |
|
88 |
|
89 aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, filter); |
|
90 aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, filter); |
|
91 } |
|
92 |
|
93 /* |
|
94 * TextureHost implementations for the OpenGL backend. |
|
95 * |
|
96 * Note that it is important to be careful about the ownership model with |
|
97 * the OpenGL backend, due to some widget limitation on Linux: before |
|
98 * the nsBaseWidget associated with our OpenGL context has been completely |
|
99 * deleted, every resource belonging to the OpenGL context MUST have been |
|
100 * released. At the moment the teardown sequence happens in the middle of |
|
101 * the nsBaseWidget's destructor, meaning that at a given moment we must be |
|
102 * able to easily find and release all the GL resources. |
|
103 * The point is: be careful about the ownership model and limit the number |
|
104 * of objects sharing references to GL resources to make the tear down |
|
105 * sequence as simple as possible. |
|
106 */ |
|
107 |
|
108 /** |
|
109 * TextureSourceOGL provides the necessary API for CompositorOGL to composite |
|
110 * a TextureSource. |
|
111 */ |
|
112 class TextureSourceOGL |
|
113 { |
|
114 public: |
|
115 TextureSourceOGL() |
|
116 : mHasCachedFilter(false) |
|
117 {} |
|
118 |
|
119 virtual bool IsValid() const = 0; |
|
120 |
|
121 virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) = 0; |
|
122 |
|
123 virtual gfx::IntSize GetSize() const = 0; |
|
124 |
|
125 virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; } |
|
126 |
|
127 virtual gfx::SurfaceFormat GetFormat() const = 0; |
|
128 |
|
129 virtual GLenum GetWrapMode() const = 0; |
|
130 |
|
131 virtual gfx::Matrix4x4 GetTextureTransform() { return gfx::Matrix4x4(); } |
|
132 |
|
133 virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() { return nullptr; } |
|
134 |
|
135 void SetFilter(gl::GLContext* aGL, gfx::Filter aFilter) |
|
136 { |
|
137 if (mHasCachedFilter && |
|
138 mCachedFilter == aFilter) { |
|
139 return; |
|
140 } |
|
141 mHasCachedFilter = true; |
|
142 mCachedFilter = aFilter; |
|
143 ApplyFilterToBoundTexture(aGL, aFilter, GetTextureTarget()); |
|
144 } |
|
145 |
|
146 void ClearCachedFilter() { mHasCachedFilter = false; } |
|
147 |
|
148 private: |
|
149 gfx::Filter mCachedFilter; |
|
150 bool mHasCachedFilter; |
|
151 }; |
|
152 |
|
153 /** |
|
154 * TextureHostOGL provides the necessary API for platform specific composition. |
|
155 */ |
|
156 class TextureHostOGL |
|
157 { |
|
158 public: |
|
159 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 |
|
160 |
|
161 /** |
|
162 * Store a fence that will signal when the current buffer is no longer being read. |
|
163 * Similar to android's GLConsumer::setReleaseFence() |
|
164 */ |
|
165 virtual bool SetReleaseFence(const android::sp<android::Fence>& aReleaseFence); |
|
166 |
|
167 /** |
|
168 * Return a releaseFence's Fence and clear a reference to the Fence. |
|
169 */ |
|
170 virtual android::sp<android::Fence> GetAndResetReleaseFence(); |
|
171 |
|
172 protected: |
|
173 android::sp<android::Fence> mReleaseFence; |
|
174 |
|
175 /** |
|
176 * Hold previous ReleaseFence to prevent Fence delivery failure via gecko IPC. |
|
177 * Fence is a kernel object and its lifetime is managed by a reference count. |
|
178 * Until the Fence is delivered to client side, need to hold Fence on host side. |
|
179 */ |
|
180 android::sp<android::Fence> mPrevReleaseFence; |
|
181 #endif |
|
182 }; |
|
183 |
|
184 /** |
|
185 * A TextureSource backed by a TextureImage. |
|
186 * |
|
187 * Depending on the underlying TextureImage, may support texture tiling, so |
|
188 * make sure to check AsTileIterator() and use the texture accordingly. |
|
189 * |
|
190 * This TextureSource can be used without a TextureHost and manage it's own |
|
191 * GL texture(s). |
|
192 */ |
|
193 class TextureImageTextureSourceOGL : public DataTextureSource |
|
194 , public TextureSourceOGL |
|
195 , public TileIterator |
|
196 { |
|
197 public: |
|
198 TextureImageTextureSourceOGL(gl::GLContext* aGL, |
|
199 TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT) |
|
200 : mGL(aGL) |
|
201 , mFlags(aFlags) |
|
202 , mIterating(false) |
|
203 {} |
|
204 |
|
205 // DataTextureSource |
|
206 |
|
207 virtual bool Update(gfx::DataSourceSurface* aSurface, |
|
208 nsIntRegion* aDestRegion = nullptr, |
|
209 gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE; |
|
210 |
|
211 void EnsureBuffer(const nsIntSize& aSize, |
|
212 gfxContentType aContentType); |
|
213 |
|
214 void CopyTo(const nsIntRect& aSourceRect, |
|
215 DataTextureSource* aDest, |
|
216 const nsIntRect& aDestRect); |
|
217 |
|
218 virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() { return this; } |
|
219 |
|
220 // TextureSource |
|
221 |
|
222 virtual void DeallocateDeviceData() MOZ_OVERRIDE |
|
223 { |
|
224 mTexImage = nullptr; |
|
225 SetUpdateSerial(0); |
|
226 } |
|
227 |
|
228 virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; } |
|
229 |
|
230 virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE; |
|
231 |
|
232 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE; |
|
233 |
|
234 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; |
|
235 |
|
236 virtual bool IsValid() const MOZ_OVERRIDE { return !!mTexImage; } |
|
237 |
|
238 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
239 |
|
240 virtual GLenum GetWrapMode() const MOZ_OVERRIDE |
|
241 { |
|
242 return mTexImage->GetWrapMode(); |
|
243 } |
|
244 |
|
245 // TileIterator |
|
246 |
|
247 virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return this; } |
|
248 |
|
249 virtual void BeginTileIteration() MOZ_OVERRIDE |
|
250 { |
|
251 mTexImage->BeginTileIteration(); |
|
252 mIterating = true; |
|
253 } |
|
254 |
|
255 virtual void EndTileIteration() MOZ_OVERRIDE |
|
256 { |
|
257 mIterating = false; |
|
258 } |
|
259 |
|
260 virtual nsIntRect GetTileRect() MOZ_OVERRIDE; |
|
261 |
|
262 virtual size_t GetTileCount() MOZ_OVERRIDE |
|
263 { |
|
264 return mTexImage->GetTileCount(); |
|
265 } |
|
266 |
|
267 virtual bool NextTile() MOZ_OVERRIDE |
|
268 { |
|
269 return mTexImage->NextTile(); |
|
270 } |
|
271 |
|
272 protected: |
|
273 nsRefPtr<gl::TextureImage> mTexImage; |
|
274 gl::GLContext* mGL; |
|
275 TextureFlags mFlags; |
|
276 bool mIterating; |
|
277 }; |
|
278 |
|
279 /** |
|
280 * A texture source meant for use with SharedTextureHostOGL. |
|
281 * |
|
282 * It does not own any GL texture, and attaches its shared handle to one of |
|
283 * the compositor's temporary textures when binding. |
|
284 * |
|
285 * The shared texture handle is owned by the TextureHost. |
|
286 */ |
|
287 class SharedTextureSourceOGL : public NewTextureSource |
|
288 , public TextureSourceOGL |
|
289 { |
|
290 public: |
|
291 typedef gl::SharedTextureShareType SharedTextureShareType; |
|
292 |
|
293 SharedTextureSourceOGL(CompositorOGL* aCompositor, |
|
294 gl::SharedTextureHandle aHandle, |
|
295 gfx::SurfaceFormat aFormat, |
|
296 GLenum aTarget, |
|
297 GLenum aWrapMode, |
|
298 SharedTextureShareType aShareType, |
|
299 gfx::IntSize aSize); |
|
300 |
|
301 virtual TextureSourceOGL* AsSourceOGL() { return this; } |
|
302 |
|
303 virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE; |
|
304 |
|
305 virtual bool IsValid() const MOZ_OVERRIDE; |
|
306 |
|
307 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } |
|
308 |
|
309 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } |
|
310 |
|
311 virtual gfx::Matrix4x4 GetTextureTransform() MOZ_OVERRIDE; |
|
312 |
|
313 virtual GLenum GetTextureTarget() const { return mTextureTarget; } |
|
314 |
|
315 virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; } |
|
316 |
|
317 // SharedTextureSource doesn't own any gl texture |
|
318 virtual void DeallocateDeviceData() {} |
|
319 |
|
320 void DetachSharedHandle(); |
|
321 |
|
322 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
323 |
|
324 gl::GLContext* gl() const; |
|
325 |
|
326 protected: |
|
327 gfx::IntSize mSize; |
|
328 CompositorOGL* mCompositor; |
|
329 gl::SharedTextureHandle mSharedHandle; |
|
330 gfx::SurfaceFormat mFormat; |
|
331 SharedTextureShareType mShareType; |
|
332 GLenum mTextureTarget; |
|
333 GLenum mWrapMode; |
|
334 }; |
|
335 |
|
336 /** |
|
337 * A TextureHost for shared GL Textures |
|
338 * |
|
339 * Most of the logic actually happens in SharedTextureSourceOGL. |
|
340 */ |
|
341 class SharedTextureHostOGL : public TextureHost |
|
342 { |
|
343 public: |
|
344 SharedTextureHostOGL(TextureFlags aFlags, |
|
345 gl::SharedTextureShareType aShareType, |
|
346 gl::SharedTextureHandle aSharedhandle, |
|
347 gfx::IntSize aSize, |
|
348 bool inverted); |
|
349 |
|
350 virtual ~SharedTextureHostOGL(); |
|
351 |
|
352 // SharedTextureHostOGL doesn't own any GL texture |
|
353 virtual void DeallocateDeviceData() MOZ_OVERRIDE {} |
|
354 |
|
355 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
356 |
|
357 virtual bool Lock() MOZ_OVERRIDE; |
|
358 |
|
359 virtual void Unlock() MOZ_OVERRIDE; |
|
360 |
|
361 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; |
|
362 |
|
363 virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE |
|
364 { |
|
365 return mTextureSource; |
|
366 } |
|
367 |
|
368 virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE |
|
369 { |
|
370 return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) |
|
371 } |
|
372 |
|
373 gl::GLContext* gl() const; |
|
374 |
|
375 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } |
|
376 |
|
377 virtual const char* Name() { return "SharedTextureHostOGL"; } |
|
378 |
|
379 protected: |
|
380 gfx::IntSize mSize; |
|
381 CompositorOGL* mCompositor; |
|
382 gl::SharedTextureHandle mSharedHandle; |
|
383 gl::SharedTextureShareType mShareType; |
|
384 |
|
385 RefPtr<SharedTextureSourceOGL> mTextureSource; |
|
386 }; |
|
387 |
|
388 /** |
|
389 * A texture source meant for use with StreamTextureHostOGL. |
|
390 * |
|
391 * It does not own any texture, we get texture from SurfaceStream. |
|
392 */ |
|
393 class StreamTextureSourceOGL : public NewTextureSource |
|
394 , public TextureSourceOGL |
|
395 { |
|
396 public: |
|
397 StreamTextureSourceOGL(CompositorOGL* aCompositor, |
|
398 gfx::SurfaceStream* aStream) |
|
399 : mCompositor(aCompositor) |
|
400 , mStream(aStream) |
|
401 , mTextureHandle(0) |
|
402 , mTextureTarget(LOCAL_GL_TEXTURE_2D) |
|
403 , mUploadTexture(0) |
|
404 , mFormat(gfx::SurfaceFormat::UNKNOWN) |
|
405 { |
|
406 MOZ_COUNT_CTOR(StreamTextureSourceOGL); |
|
407 } |
|
408 |
|
409 ~StreamTextureSourceOGL() |
|
410 { |
|
411 MOZ_COUNT_DTOR(StreamTextureSourceOGL); |
|
412 } |
|
413 |
|
414 virtual TextureSourceOGL* AsSourceOGL() { return this; } |
|
415 |
|
416 virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE; |
|
417 |
|
418 virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); } |
|
419 |
|
420 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } |
|
421 |
|
422 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } |
|
423 |
|
424 virtual GLenum GetTextureTarget() const { return mTextureTarget; } |
|
425 |
|
426 virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; } |
|
427 |
|
428 virtual void DeallocateDeviceData(); |
|
429 |
|
430 bool RetrieveTextureFromStream(); |
|
431 |
|
432 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
433 |
|
434 protected: |
|
435 gl::GLContext* gl() const; |
|
436 |
|
437 CompositorOGL* mCompositor; |
|
438 gfx::SurfaceStream* mStream; |
|
439 GLuint mTextureHandle; |
|
440 GLenum mTextureTarget; |
|
441 GLuint mUploadTexture; |
|
442 gfx::IntSize mSize; |
|
443 gfx::SurfaceFormat mFormat; |
|
444 }; |
|
445 |
|
446 /** |
|
447 * A TextureHost for shared SurfaceStream |
|
448 */ |
|
449 class StreamTextureHostOGL : public TextureHost |
|
450 { |
|
451 public: |
|
452 StreamTextureHostOGL(TextureFlags aFlags, |
|
453 const SurfaceStreamDescriptor& aDesc); |
|
454 |
|
455 virtual ~StreamTextureHostOGL(); |
|
456 |
|
457 // SharedTextureHostOGL doesn't own any GL texture |
|
458 virtual void DeallocateDeviceData() MOZ_OVERRIDE {} |
|
459 |
|
460 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
461 |
|
462 virtual bool Lock() MOZ_OVERRIDE; |
|
463 |
|
464 virtual void Unlock() MOZ_OVERRIDE; |
|
465 |
|
466 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; |
|
467 |
|
468 virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE |
|
469 { |
|
470 return mTextureSource; |
|
471 } |
|
472 |
|
473 virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE |
|
474 { |
|
475 return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) |
|
476 } |
|
477 |
|
478 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE; |
|
479 |
|
480 #ifdef MOZ_LAYERS_HAVE_LOG |
|
481 virtual const char* Name() { return "StreamTextureHostOGL"; } |
|
482 #endif |
|
483 |
|
484 protected: |
|
485 CompositorOGL* mCompositor; |
|
486 gfx::SurfaceStream* mStream; |
|
487 RefPtr<StreamTextureSourceOGL> mTextureSource; |
|
488 }; |
|
489 |
|
490 } // namespace |
|
491 } // namespace |
|
492 |
|
493 #endif /* MOZILLA_GFX_TEXTUREOGL_H */ |