1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/opengl/TextureHostOGL.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,493 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef MOZILLA_GFX_TEXTUREOGL_H 1.10 +#define MOZILLA_GFX_TEXTUREOGL_H 1.11 + 1.12 +#include <stddef.h> // for size_t 1.13 +#include <stdint.h> // for uint64_t 1.14 +#include "CompositableHost.h" 1.15 +#include "GLContextTypes.h" // for GLContext 1.16 +#include "GLDefs.h" // for GLenum, LOCAL_GL_CLAMP_TO_EDGE, etc 1.17 +#include "GLTextureImage.h" // for TextureImage 1.18 +#include "gfxTypes.h" 1.19 +#include "mozilla/GfxMessageUtils.h" // for gfxContentType 1.20 +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 1.21 +#include "mozilla/Attributes.h" // for MOZ_OVERRIDE 1.22 +#include "mozilla/RefPtr.h" // for RefPtr 1.23 +#include "mozilla/gfx/Matrix.h" // for Matrix4x4 1.24 +#include "mozilla/gfx/Point.h" // for IntSize, IntPoint 1.25 +#include "mozilla/gfx/Types.h" // for SurfaceFormat, etc 1.26 +#include "mozilla/layers/CompositorTypes.h" // for TextureFlags 1.27 +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor 1.28 +#include "mozilla/layers/TextureHost.h" // for TextureHost, etc 1.29 +#include "mozilla/mozalloc.h" // for operator delete, etc 1.30 +#include "nsAutoPtr.h" // for nsRefPtr 1.31 +#include "nsCOMPtr.h" // for already_AddRefed 1.32 +#include "nsDebug.h" // for NS_WARNING 1.33 +#include "nsISupportsImpl.h" // for TextureImage::Release, etc 1.34 +#include "OGLShaderProgram.h" // for ShaderProgramType, etc 1.35 +#ifdef MOZ_WIDGET_GONK 1.36 +#include <ui/GraphicBuffer.h> 1.37 +#if ANDROID_VERSION >= 17 1.38 +#include <ui/Fence.h> 1.39 +#endif 1.40 +#endif 1.41 + 1.42 +class gfxReusableSurfaceWrapper; 1.43 +class nsIntRegion; 1.44 +struct nsIntPoint; 1.45 +struct nsIntRect; 1.46 +struct nsIntSize; 1.47 + 1.48 +namespace mozilla { 1.49 +namespace gfx { 1.50 +class DataSourceSurface; 1.51 +class SurfaceStream; 1.52 +} 1.53 + 1.54 +namespace layers { 1.55 + 1.56 +class Compositor; 1.57 +class CompositorOGL; 1.58 +class TextureImageTextureSourceOGL; 1.59 + 1.60 +/** 1.61 + * CompositableBackendSpecificData implementation for the Gonk OpenGL backend. 1.62 + * Share a same texture between TextureHosts in the same CompositableHost. 1.63 + * By shareing the texture among the TextureHosts, number of texture allocations 1.64 + * can be reduced than texture allocation in every TextureHosts. 1.65 + * From Bug 912134, use only one texture among all TextureHosts degrade 1.66 + * the rendering performance. 1.67 + * CompositableDataGonkOGL chooses in a middile of them. 1.68 + */ 1.69 +class CompositableDataGonkOGL : public CompositableBackendSpecificData 1.70 +{ 1.71 +public: 1.72 + CompositableDataGonkOGL(); 1.73 + virtual ~CompositableDataGonkOGL(); 1.74 + 1.75 + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; 1.76 + virtual void ClearData() MOZ_OVERRIDE; 1.77 + GLuint GetTexture(); 1.78 + void DeleteTextureIfPresent(); 1.79 + gl::GLContext* gl() const; 1.80 +protected: 1.81 + RefPtr<CompositorOGL> mCompositor; 1.82 + GLuint mTexture; 1.83 +}; 1.84 + 1.85 +inline void ApplyFilterToBoundTexture(gl::GLContext* aGL, 1.86 + gfx::Filter aFilter, 1.87 + GLuint aTarget = LOCAL_GL_TEXTURE_2D) 1.88 +{ 1.89 + GLenum filter = 1.90 + (aFilter == gfx::Filter::POINT ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR); 1.91 + 1.92 + aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, filter); 1.93 + aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, filter); 1.94 +} 1.95 + 1.96 +/* 1.97 + * TextureHost implementations for the OpenGL backend. 1.98 + * 1.99 + * Note that it is important to be careful about the ownership model with 1.100 + * the OpenGL backend, due to some widget limitation on Linux: before 1.101 + * the nsBaseWidget associated with our OpenGL context has been completely 1.102 + * deleted, every resource belonging to the OpenGL context MUST have been 1.103 + * released. At the moment the teardown sequence happens in the middle of 1.104 + * the nsBaseWidget's destructor, meaning that at a given moment we must be 1.105 + * able to easily find and release all the GL resources. 1.106 + * The point is: be careful about the ownership model and limit the number 1.107 + * of objects sharing references to GL resources to make the tear down 1.108 + * sequence as simple as possible. 1.109 + */ 1.110 + 1.111 +/** 1.112 + * TextureSourceOGL provides the necessary API for CompositorOGL to composite 1.113 + * a TextureSource. 1.114 + */ 1.115 +class TextureSourceOGL 1.116 +{ 1.117 +public: 1.118 + TextureSourceOGL() 1.119 + : mHasCachedFilter(false) 1.120 + {} 1.121 + 1.122 + virtual bool IsValid() const = 0; 1.123 + 1.124 + virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) = 0; 1.125 + 1.126 + virtual gfx::IntSize GetSize() const = 0; 1.127 + 1.128 + virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; } 1.129 + 1.130 + virtual gfx::SurfaceFormat GetFormat() const = 0; 1.131 + 1.132 + virtual GLenum GetWrapMode() const = 0; 1.133 + 1.134 + virtual gfx::Matrix4x4 GetTextureTransform() { return gfx::Matrix4x4(); } 1.135 + 1.136 + virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() { return nullptr; } 1.137 + 1.138 + void SetFilter(gl::GLContext* aGL, gfx::Filter aFilter) 1.139 + { 1.140 + if (mHasCachedFilter && 1.141 + mCachedFilter == aFilter) { 1.142 + return; 1.143 + } 1.144 + mHasCachedFilter = true; 1.145 + mCachedFilter = aFilter; 1.146 + ApplyFilterToBoundTexture(aGL, aFilter, GetTextureTarget()); 1.147 + } 1.148 + 1.149 + void ClearCachedFilter() { mHasCachedFilter = false; } 1.150 + 1.151 +private: 1.152 + gfx::Filter mCachedFilter; 1.153 + bool mHasCachedFilter; 1.154 +}; 1.155 + 1.156 +/** 1.157 + * TextureHostOGL provides the necessary API for platform specific composition. 1.158 + */ 1.159 +class TextureHostOGL 1.160 +{ 1.161 +public: 1.162 +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 1.163 + 1.164 + /** 1.165 + * Store a fence that will signal when the current buffer is no longer being read. 1.166 + * Similar to android's GLConsumer::setReleaseFence() 1.167 + */ 1.168 + virtual bool SetReleaseFence(const android::sp<android::Fence>& aReleaseFence); 1.169 + 1.170 + /** 1.171 + * Return a releaseFence's Fence and clear a reference to the Fence. 1.172 + */ 1.173 + virtual android::sp<android::Fence> GetAndResetReleaseFence(); 1.174 + 1.175 +protected: 1.176 + android::sp<android::Fence> mReleaseFence; 1.177 + 1.178 + /** 1.179 + * Hold previous ReleaseFence to prevent Fence delivery failure via gecko IPC. 1.180 + * Fence is a kernel object and its lifetime is managed by a reference count. 1.181 + * Until the Fence is delivered to client side, need to hold Fence on host side. 1.182 + */ 1.183 + android::sp<android::Fence> mPrevReleaseFence; 1.184 +#endif 1.185 +}; 1.186 + 1.187 +/** 1.188 + * A TextureSource backed by a TextureImage. 1.189 + * 1.190 + * Depending on the underlying TextureImage, may support texture tiling, so 1.191 + * make sure to check AsTileIterator() and use the texture accordingly. 1.192 + * 1.193 + * This TextureSource can be used without a TextureHost and manage it's own 1.194 + * GL texture(s). 1.195 + */ 1.196 +class TextureImageTextureSourceOGL : public DataTextureSource 1.197 + , public TextureSourceOGL 1.198 + , public TileIterator 1.199 +{ 1.200 +public: 1.201 + TextureImageTextureSourceOGL(gl::GLContext* aGL, 1.202 + TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT) 1.203 + : mGL(aGL) 1.204 + , mFlags(aFlags) 1.205 + , mIterating(false) 1.206 + {} 1.207 + 1.208 + // DataTextureSource 1.209 + 1.210 + virtual bool Update(gfx::DataSourceSurface* aSurface, 1.211 + nsIntRegion* aDestRegion = nullptr, 1.212 + gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE; 1.213 + 1.214 + void EnsureBuffer(const nsIntSize& aSize, 1.215 + gfxContentType aContentType); 1.216 + 1.217 + void CopyTo(const nsIntRect& aSourceRect, 1.218 + DataTextureSource* aDest, 1.219 + const nsIntRect& aDestRect); 1.220 + 1.221 + virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() { return this; } 1.222 + 1.223 + // TextureSource 1.224 + 1.225 + virtual void DeallocateDeviceData() MOZ_OVERRIDE 1.226 + { 1.227 + mTexImage = nullptr; 1.228 + SetUpdateSerial(0); 1.229 + } 1.230 + 1.231 + virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; } 1.232 + 1.233 + virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE; 1.234 + 1.235 + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE; 1.236 + 1.237 + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; 1.238 + 1.239 + virtual bool IsValid() const MOZ_OVERRIDE { return !!mTexImage; } 1.240 + 1.241 + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; 1.242 + 1.243 + virtual GLenum GetWrapMode() const MOZ_OVERRIDE 1.244 + { 1.245 + return mTexImage->GetWrapMode(); 1.246 + } 1.247 + 1.248 + // TileIterator 1.249 + 1.250 + virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return this; } 1.251 + 1.252 + virtual void BeginTileIteration() MOZ_OVERRIDE 1.253 + { 1.254 + mTexImage->BeginTileIteration(); 1.255 + mIterating = true; 1.256 + } 1.257 + 1.258 + virtual void EndTileIteration() MOZ_OVERRIDE 1.259 + { 1.260 + mIterating = false; 1.261 + } 1.262 + 1.263 + virtual nsIntRect GetTileRect() MOZ_OVERRIDE; 1.264 + 1.265 + virtual size_t GetTileCount() MOZ_OVERRIDE 1.266 + { 1.267 + return mTexImage->GetTileCount(); 1.268 + } 1.269 + 1.270 + virtual bool NextTile() MOZ_OVERRIDE 1.271 + { 1.272 + return mTexImage->NextTile(); 1.273 + } 1.274 + 1.275 +protected: 1.276 + nsRefPtr<gl::TextureImage> mTexImage; 1.277 + gl::GLContext* mGL; 1.278 + TextureFlags mFlags; 1.279 + bool mIterating; 1.280 +}; 1.281 + 1.282 +/** 1.283 + * A texture source meant for use with SharedTextureHostOGL. 1.284 + * 1.285 + * It does not own any GL texture, and attaches its shared handle to one of 1.286 + * the compositor's temporary textures when binding. 1.287 + * 1.288 + * The shared texture handle is owned by the TextureHost. 1.289 + */ 1.290 +class SharedTextureSourceOGL : public NewTextureSource 1.291 + , public TextureSourceOGL 1.292 +{ 1.293 +public: 1.294 + typedef gl::SharedTextureShareType SharedTextureShareType; 1.295 + 1.296 + SharedTextureSourceOGL(CompositorOGL* aCompositor, 1.297 + gl::SharedTextureHandle aHandle, 1.298 + gfx::SurfaceFormat aFormat, 1.299 + GLenum aTarget, 1.300 + GLenum aWrapMode, 1.301 + SharedTextureShareType aShareType, 1.302 + gfx::IntSize aSize); 1.303 + 1.304 + virtual TextureSourceOGL* AsSourceOGL() { return this; } 1.305 + 1.306 + virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE; 1.307 + 1.308 + virtual bool IsValid() const MOZ_OVERRIDE; 1.309 + 1.310 + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } 1.311 + 1.312 + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } 1.313 + 1.314 + virtual gfx::Matrix4x4 GetTextureTransform() MOZ_OVERRIDE; 1.315 + 1.316 + virtual GLenum GetTextureTarget() const { return mTextureTarget; } 1.317 + 1.318 + virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; } 1.319 + 1.320 + // SharedTextureSource doesn't own any gl texture 1.321 + virtual void DeallocateDeviceData() {} 1.322 + 1.323 + void DetachSharedHandle(); 1.324 + 1.325 + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; 1.326 + 1.327 + gl::GLContext* gl() const; 1.328 + 1.329 +protected: 1.330 + gfx::IntSize mSize; 1.331 + CompositorOGL* mCompositor; 1.332 + gl::SharedTextureHandle mSharedHandle; 1.333 + gfx::SurfaceFormat mFormat; 1.334 + SharedTextureShareType mShareType; 1.335 + GLenum mTextureTarget; 1.336 + GLenum mWrapMode; 1.337 +}; 1.338 + 1.339 +/** 1.340 + * A TextureHost for shared GL Textures 1.341 + * 1.342 + * Most of the logic actually happens in SharedTextureSourceOGL. 1.343 + */ 1.344 +class SharedTextureHostOGL : public TextureHost 1.345 +{ 1.346 +public: 1.347 + SharedTextureHostOGL(TextureFlags aFlags, 1.348 + gl::SharedTextureShareType aShareType, 1.349 + gl::SharedTextureHandle aSharedhandle, 1.350 + gfx::IntSize aSize, 1.351 + bool inverted); 1.352 + 1.353 + virtual ~SharedTextureHostOGL(); 1.354 + 1.355 + // SharedTextureHostOGL doesn't own any GL texture 1.356 + virtual void DeallocateDeviceData() MOZ_OVERRIDE {} 1.357 + 1.358 + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; 1.359 + 1.360 + virtual bool Lock() MOZ_OVERRIDE; 1.361 + 1.362 + virtual void Unlock() MOZ_OVERRIDE; 1.363 + 1.364 + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; 1.365 + 1.366 + virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE 1.367 + { 1.368 + return mTextureSource; 1.369 + } 1.370 + 1.371 + virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE 1.372 + { 1.373 + return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) 1.374 + } 1.375 + 1.376 + gl::GLContext* gl() const; 1.377 + 1.378 + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } 1.379 + 1.380 + virtual const char* Name() { return "SharedTextureHostOGL"; } 1.381 + 1.382 +protected: 1.383 + gfx::IntSize mSize; 1.384 + CompositorOGL* mCompositor; 1.385 + gl::SharedTextureHandle mSharedHandle; 1.386 + gl::SharedTextureShareType mShareType; 1.387 + 1.388 + RefPtr<SharedTextureSourceOGL> mTextureSource; 1.389 +}; 1.390 + 1.391 +/** 1.392 + * A texture source meant for use with StreamTextureHostOGL. 1.393 + * 1.394 + * It does not own any texture, we get texture from SurfaceStream. 1.395 + */ 1.396 +class StreamTextureSourceOGL : public NewTextureSource 1.397 + , public TextureSourceOGL 1.398 +{ 1.399 +public: 1.400 + StreamTextureSourceOGL(CompositorOGL* aCompositor, 1.401 + gfx::SurfaceStream* aStream) 1.402 + : mCompositor(aCompositor) 1.403 + , mStream(aStream) 1.404 + , mTextureHandle(0) 1.405 + , mTextureTarget(LOCAL_GL_TEXTURE_2D) 1.406 + , mUploadTexture(0) 1.407 + , mFormat(gfx::SurfaceFormat::UNKNOWN) 1.408 + { 1.409 + MOZ_COUNT_CTOR(StreamTextureSourceOGL); 1.410 + } 1.411 + 1.412 + ~StreamTextureSourceOGL() 1.413 + { 1.414 + MOZ_COUNT_DTOR(StreamTextureSourceOGL); 1.415 + } 1.416 + 1.417 + virtual TextureSourceOGL* AsSourceOGL() { return this; } 1.418 + 1.419 + virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE; 1.420 + 1.421 + virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); } 1.422 + 1.423 + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } 1.424 + 1.425 + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } 1.426 + 1.427 + virtual GLenum GetTextureTarget() const { return mTextureTarget; } 1.428 + 1.429 + virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; } 1.430 + 1.431 + virtual void DeallocateDeviceData(); 1.432 + 1.433 + bool RetrieveTextureFromStream(); 1.434 + 1.435 + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; 1.436 + 1.437 +protected: 1.438 + gl::GLContext* gl() const; 1.439 + 1.440 + CompositorOGL* mCompositor; 1.441 + gfx::SurfaceStream* mStream; 1.442 + GLuint mTextureHandle; 1.443 + GLenum mTextureTarget; 1.444 + GLuint mUploadTexture; 1.445 + gfx::IntSize mSize; 1.446 + gfx::SurfaceFormat mFormat; 1.447 +}; 1.448 + 1.449 +/** 1.450 + * A TextureHost for shared SurfaceStream 1.451 + */ 1.452 +class StreamTextureHostOGL : public TextureHost 1.453 +{ 1.454 +public: 1.455 + StreamTextureHostOGL(TextureFlags aFlags, 1.456 + const SurfaceStreamDescriptor& aDesc); 1.457 + 1.458 + virtual ~StreamTextureHostOGL(); 1.459 + 1.460 + // SharedTextureHostOGL doesn't own any GL texture 1.461 + virtual void DeallocateDeviceData() MOZ_OVERRIDE {} 1.462 + 1.463 + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; 1.464 + 1.465 + virtual bool Lock() MOZ_OVERRIDE; 1.466 + 1.467 + virtual void Unlock() MOZ_OVERRIDE; 1.468 + 1.469 + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE; 1.470 + 1.471 + virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE 1.472 + { 1.473 + return mTextureSource; 1.474 + } 1.475 + 1.476 + virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE 1.477 + { 1.478 + return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) 1.479 + } 1.480 + 1.481 + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE; 1.482 + 1.483 +#ifdef MOZ_LAYERS_HAVE_LOG 1.484 + virtual const char* Name() { return "StreamTextureHostOGL"; } 1.485 +#endif 1.486 + 1.487 +protected: 1.488 + CompositorOGL* mCompositor; 1.489 + gfx::SurfaceStream* mStream; 1.490 + RefPtr<StreamTextureSourceOGL> mTextureSource; 1.491 +}; 1.492 + 1.493 +} // namespace 1.494 +} // namespace 1.495 + 1.496 +#endif /* MOZILLA_GFX_TEXTUREOGL_H */