1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/composite/ContentHost.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,391 @@ 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 GFX_CONTENTHOST_H 1.10 +#define GFX_CONTENTHOST_H 1.11 + 1.12 +#include <stdint.h> // for uint32_t 1.13 +#include <stdio.h> // for FILE 1.14 +#include "mozilla-config.h" // for MOZ_DUMP_PAINTING 1.15 +#include "CompositableHost.h" // for CompositableHost, etc 1.16 +#include "RotatedBuffer.h" // for RotatedContentBuffer, etc 1.17 +#include "mozilla/Attributes.h" // for MOZ_OVERRIDE 1.18 +#include "mozilla/RefPtr.h" // for RefPtr 1.19 +#include "mozilla/gfx/BasePoint.h" // for BasePoint 1.20 +#include "mozilla/gfx/Point.h" // for Point 1.21 +#include "mozilla/gfx/Rect.h" // for Rect 1.22 +#include "mozilla/gfx/Types.h" // for Filter 1.23 +#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc 1.24 +#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator 1.25 +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor 1.26 +#include "mozilla/layers/LayersTypes.h" // for etc 1.27 +#include "mozilla/layers/TextureHost.h" // for TextureHost 1.28 +#include "mozilla/mozalloc.h" // for operator delete 1.29 +#include "nsAutoPtr.h" // for nsAutoPtr 1.30 +#include "nsCOMPtr.h" // for already_AddRefed 1.31 +#include "nsDebug.h" // for NS_RUNTIMEABORT 1.32 +#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc 1.33 +#include "nsPoint.h" // for nsIntPoint 1.34 +#include "nsRect.h" // for nsIntRect 1.35 +#include "nsRegion.h" // for nsIntRegion 1.36 +#include "nsTArray.h" // for nsTArray 1.37 +#include "nscore.h" // for nsACString 1.38 + 1.39 +namespace mozilla { 1.40 +namespace gfx { 1.41 +class Matrix4x4; 1.42 +} 1.43 +namespace layers { 1.44 +class Compositor; 1.45 +class ThebesBufferData; 1.46 +class TiledLayerComposer; 1.47 +struct EffectChain; 1.48 +class TextureImageTextureSourceOGL; 1.49 + 1.50 +struct TexturedEffect; 1.51 + 1.52 +/** 1.53 + * ContentHosts are used for compositing Thebes layers, always matched by a 1.54 + * ContentClient of the same type. 1.55 + * 1.56 + * ContentHosts support only UpdateThebes(), not Update(). 1.57 + */ 1.58 +class ContentHost : public CompositableHost 1.59 +{ 1.60 +public: 1.61 + // Subclasses should implement this method if they support being used as a 1.62 + // tiling. 1.63 + virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; } 1.64 + 1.65 + virtual bool UpdateThebes(const ThebesBufferData& aData, 1.66 + const nsIntRegion& aUpdated, 1.67 + const nsIntRegion& aOldValidRegionBack, 1.68 + nsIntRegion* aUpdatedRegionBack) = 0; 1.69 + 1.70 + virtual void SetPaintWillResample(bool aResample) { } 1.71 + 1.72 +protected: 1.73 + ContentHost(const TextureInfo& aTextureInfo) 1.74 + : CompositableHost(aTextureInfo) 1.75 + {} 1.76 +}; 1.77 + 1.78 +/** 1.79 + * Base class for non-tiled ContentHosts. 1.80 + * 1.81 + * Ownership of the SurfaceDescriptor and the resources it represents is passed 1.82 + * from the ContentClient to the ContentHost when the TextureClient/Hosts are 1.83 + * created, that is recevied here by SetTextureHosts which assigns one or two 1.84 + * texture hosts (for single and double buffering) to the ContentHost. 1.85 + * 1.86 + * It is the responsibility of the ContentHost to destroy its resources when 1.87 + * they are recreated or the ContentHost dies. 1.88 + */ 1.89 +class ContentHostBase : public ContentHost 1.90 +{ 1.91 +public: 1.92 + typedef RotatedContentBuffer::ContentType ContentType; 1.93 + typedef RotatedContentBuffer::PaintState PaintState; 1.94 + 1.95 + ContentHostBase(const TextureInfo& aTextureInfo); 1.96 + virtual ~ContentHostBase(); 1.97 + 1.98 + virtual void Composite(EffectChain& aEffectChain, 1.99 + float aOpacity, 1.100 + const gfx::Matrix4x4& aTransform, 1.101 + const gfx::Filter& aFilter, 1.102 + const gfx::Rect& aClipRect, 1.103 + const nsIntRegion* aVisibleRegion = nullptr, 1.104 + TiledLayerProperties* aLayerProperties = nullptr); 1.105 + 1.106 + virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; } 1.107 + 1.108 + virtual bool Lock() = 0; 1.109 + virtual void Unlock() = 0; 1.110 + 1.111 + virtual NewTextureSource* GetTextureSource() = 0; 1.112 + virtual NewTextureSource* GetTextureSourceOnWhite() = 0; 1.113 + 1.114 +protected: 1.115 + virtual nsIntPoint GetOriginOffset() 1.116 + { 1.117 + return mBufferRect.TopLeft() - mBufferRotation; 1.118 + } 1.119 + 1.120 + bool PaintWillResample() { return mPaintWillResample; } 1.121 + 1.122 + nsIntRect mBufferRect; 1.123 + nsIntPoint mBufferRotation; 1.124 + bool mPaintWillResample; 1.125 + bool mInitialised; 1.126 +}; 1.127 + 1.128 +/** 1.129 + * Shared ContentHostBase implementation for content hosts that 1.130 + * use up to two TextureHosts. 1.131 + */ 1.132 +class ContentHostTexture : public ContentHostBase 1.133 +{ 1.134 +public: 1.135 + ContentHostTexture(const TextureInfo& aTextureInfo) 1.136 + : ContentHostBase(aTextureInfo) 1.137 + , mLocked(false) 1.138 + { } 1.139 + 1.140 + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; 1.141 + 1.142 +#ifdef MOZ_DUMP_PAINTING 1.143 + virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE; 1.144 + 1.145 + virtual void Dump(FILE* aFile=nullptr, 1.146 + const char* aPrefix="", 1.147 + bool aDumpHtml=false) MOZ_OVERRIDE; 1.148 +#endif 1.149 + 1.150 + virtual void PrintInfo(nsACString& aTo, const char* aPrefix) MOZ_OVERRIDE; 1.151 + 1.152 + virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE; 1.153 + virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack, 1.154 + TextureHost* aTextureOnWhite) MOZ_OVERRIDE; 1.155 + 1.156 + virtual bool Lock() { 1.157 + MOZ_ASSERT(!mLocked); 1.158 + if (!mTextureHost) { 1.159 + return false; 1.160 + } 1.161 + if (!mTextureHost->Lock()) { 1.162 + return false; 1.163 + } 1.164 + 1.165 + if (mTextureHostOnWhite && !mTextureHostOnWhite->Lock()) { 1.166 + return false; 1.167 + } 1.168 + 1.169 + mLocked = true; 1.170 + return true; 1.171 + } 1.172 + virtual void Unlock() { 1.173 + MOZ_ASSERT(mLocked); 1.174 + mTextureHost->Unlock(); 1.175 + if (mTextureHostOnWhite) { 1.176 + mTextureHostOnWhite->Unlock(); 1.177 + } 1.178 + mLocked = false; 1.179 + } 1.180 + 1.181 + virtual NewTextureSource* GetTextureSource() { 1.182 + MOZ_ASSERT(mLocked); 1.183 + return mTextureHost->GetTextureSources(); 1.184 + } 1.185 + virtual NewTextureSource* GetTextureSourceOnWhite() { 1.186 + MOZ_ASSERT(mLocked); 1.187 + if (mTextureHostOnWhite) { 1.188 + return mTextureHostOnWhite->GetTextureSources(); 1.189 + } 1.190 + return nullptr; 1.191 + } 1.192 + 1.193 + LayerRenderState GetRenderState(); 1.194 + 1.195 +protected: 1.196 + RefPtr<TextureHost> mTextureHost; 1.197 + RefPtr<TextureHost> mTextureHostOnWhite; 1.198 + bool mLocked; 1.199 +}; 1.200 + 1.201 +/** 1.202 + * Double buffering is implemented by swapping the front and back TextureHosts. 1.203 + * We assume that whenever we use double buffering, then we have 1.204 + * render-to-texture and thus no texture upload to do. 1.205 + */ 1.206 +class ContentHostDoubleBuffered : public ContentHostTexture 1.207 +{ 1.208 +public: 1.209 + ContentHostDoubleBuffered(const TextureInfo& aTextureInfo) 1.210 + : ContentHostTexture(aTextureInfo) 1.211 + {} 1.212 + 1.213 + virtual ~ContentHostDoubleBuffered() {} 1.214 + 1.215 + virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_DOUBLE; } 1.216 + 1.217 + virtual bool UpdateThebes(const ThebesBufferData& aData, 1.218 + const nsIntRegion& aUpdated, 1.219 + const nsIntRegion& aOldValidRegionBack, 1.220 + nsIntRegion* aUpdatedRegionBack); 1.221 + 1.222 +protected: 1.223 + nsIntRegion mValidRegionForNextBackBuffer; 1.224 +}; 1.225 + 1.226 +/** 1.227 + * Single buffered, therefore we must synchronously upload the image from the 1.228 + * TextureHost in the layers transaction (i.e., in UpdateThebes). 1.229 + */ 1.230 +class ContentHostSingleBuffered : public ContentHostTexture 1.231 +{ 1.232 +public: 1.233 + ContentHostSingleBuffered(const TextureInfo& aTextureInfo) 1.234 + : ContentHostTexture(aTextureInfo) 1.235 + {} 1.236 + virtual ~ContentHostSingleBuffered() {} 1.237 + 1.238 + virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_SINGLE; } 1.239 + 1.240 + virtual bool UpdateThebes(const ThebesBufferData& aData, 1.241 + const nsIntRegion& aUpdated, 1.242 + const nsIntRegion& aOldValidRegionBack, 1.243 + nsIntRegion* aUpdatedRegionBack); 1.244 +}; 1.245 + 1.246 +/** 1.247 + * Maintains a host-side only texture, and gets provided with 1.248 + * surfaces that only cover the changed pixels during an update. 1.249 + * 1.250 + * Takes ownership of the passed in update surfaces, and must 1.251 + * free them once texture upload is complete. 1.252 + * 1.253 + * Delays texture uploads until the next composite to 1.254 + * avoid blocking the main thread. 1.255 + */ 1.256 +class ContentHostIncremental : public ContentHostBase 1.257 +{ 1.258 +public: 1.259 + ContentHostIncremental(const TextureInfo& aTextureInfo); 1.260 + ~ContentHostIncremental(); 1.261 + 1.262 + virtual CompositableType GetType() { return BUFFER_CONTENT_INC; } 1.263 + 1.264 + virtual LayerRenderState GetRenderState() MOZ_OVERRIDE { return LayerRenderState(); } 1.265 + 1.266 + virtual bool CreatedIncrementalTexture(ISurfaceAllocator* aAllocator, 1.267 + const TextureInfo& aTextureInfo, 1.268 + const nsIntRect& aBufferRect) MOZ_OVERRIDE; 1.269 + 1.270 + virtual void UpdateIncremental(TextureIdentifier aTextureId, 1.271 + SurfaceDescriptor& aSurface, 1.272 + const nsIntRegion& aUpdated, 1.273 + const nsIntRect& aBufferRect, 1.274 + const nsIntPoint& aBufferRotation) MOZ_OVERRIDE; 1.275 + 1.276 + virtual bool UpdateThebes(const ThebesBufferData& aData, 1.277 + const nsIntRegion& aUpdated, 1.278 + const nsIntRegion& aOldValidRegionBack, 1.279 + nsIntRegion* aUpdatedRegionBack) 1.280 + { 1.281 + NS_ERROR("Shouldn't call this"); 1.282 + return false; 1.283 + } 1.284 + 1.285 + virtual bool Lock() { 1.286 + MOZ_ASSERT(!mLocked); 1.287 + ProcessTextureUpdates(); 1.288 + mLocked = true; 1.289 + return true; 1.290 + } 1.291 + 1.292 + virtual void Unlock() { 1.293 + MOZ_ASSERT(mLocked); 1.294 + mLocked = false; 1.295 + } 1.296 + 1.297 + virtual NewTextureSource* GetTextureSource(); 1.298 + virtual NewTextureSource* GetTextureSourceOnWhite(); 1.299 + 1.300 +private: 1.301 + 1.302 + void FlushUpdateQueue(); 1.303 + void ProcessTextureUpdates(); 1.304 + 1.305 + class Request 1.306 + { 1.307 + public: 1.308 + Request() 1.309 + { 1.310 + MOZ_COUNT_CTOR(ContentHostIncremental::Request); 1.311 + } 1.312 + 1.313 + virtual ~Request() 1.314 + { 1.315 + MOZ_COUNT_DTOR(ContentHostIncremental::Request); 1.316 + } 1.317 + 1.318 + virtual void Execute(ContentHostIncremental *aHost) = 0; 1.319 + }; 1.320 + 1.321 + class TextureCreationRequest : public Request 1.322 + { 1.323 + public: 1.324 + TextureCreationRequest(const TextureInfo& aTextureInfo, 1.325 + const nsIntRect& aBufferRect) 1.326 + : mTextureInfo(aTextureInfo) 1.327 + , mBufferRect(aBufferRect) 1.328 + {} 1.329 + 1.330 + virtual void Execute(ContentHostIncremental *aHost); 1.331 + 1.332 + private: 1.333 + TextureInfo mTextureInfo; 1.334 + nsIntRect mBufferRect; 1.335 + }; 1.336 + 1.337 + class TextureUpdateRequest : public Request 1.338 + { 1.339 + public: 1.340 + TextureUpdateRequest(ISurfaceAllocator* aDeAllocator, 1.341 + TextureIdentifier aTextureId, 1.342 + SurfaceDescriptor& aDescriptor, 1.343 + const nsIntRegion& aUpdated, 1.344 + const nsIntRect& aBufferRect, 1.345 + const nsIntPoint& aBufferRotation) 1.346 + : mDeAllocator(aDeAllocator) 1.347 + , mTextureId(aTextureId) 1.348 + , mDescriptor(aDescriptor) 1.349 + , mUpdated(aUpdated) 1.350 + , mBufferRect(aBufferRect) 1.351 + , mBufferRotation(aBufferRotation) 1.352 + {} 1.353 + 1.354 + ~TextureUpdateRequest() 1.355 + { 1.356 + //TODO: Recycle these? 1.357 + mDeAllocator->DestroySharedSurface(&mDescriptor); 1.358 + } 1.359 + 1.360 + virtual void Execute(ContentHostIncremental *aHost); 1.361 + 1.362 + private: 1.363 + enum XSide { 1.364 + LEFT, RIGHT 1.365 + }; 1.366 + enum YSide { 1.367 + TOP, BOTTOM 1.368 + }; 1.369 + 1.370 + nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide) const; 1.371 + 1.372 + RefPtr<ISurfaceAllocator> mDeAllocator; 1.373 + TextureIdentifier mTextureId; 1.374 + SurfaceDescriptor mDescriptor; 1.375 + nsIntRegion mUpdated; 1.376 + nsIntRect mBufferRect; 1.377 + nsIntPoint mBufferRotation; 1.378 + }; 1.379 + 1.380 + nsTArray<nsAutoPtr<Request> > mUpdateList; 1.381 + 1.382 + // Specific to OGL to avoid exposing methods on TextureSource that only 1.383 + // have one implementation. 1.384 + RefPtr<TextureImageTextureSourceOGL> mSource; 1.385 + RefPtr<TextureImageTextureSourceOGL> mSourceOnWhite; 1.386 + 1.387 + RefPtr<ISurfaceAllocator> mDeAllocator; 1.388 + bool mLocked; 1.389 +}; 1.390 + 1.391 +} 1.392 +} 1.393 + 1.394 +#endif