1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/client/ClientImageLayer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,184 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; 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 +#include "ClientLayerManager.h" // for ClientLayerManager, etc 1.10 +#include "ImageContainer.h" // for AutoLockImage, etc 1.11 +#include "ImageLayers.h" // for ImageLayer 1.12 +#include "mozilla/Attributes.h" // for MOZ_OVERRIDE 1.13 +#include "mozilla/RefPtr.h" // for RefPtr 1.14 +#include "mozilla/layers/CompositorTypes.h" 1.15 +#include "mozilla/layers/ImageClient.h" // for ImageClient, etc 1.16 +#include "mozilla/layers/LayersMessages.h" // for ImageLayerAttributes, etc 1.17 +#include "mozilla/mozalloc.h" // for operator delete, etc 1.18 +#include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc 1.19 +#include "nsCOMPtr.h" // for already_AddRefed 1.20 +#include "nsDebug.h" // for NS_ASSERTION 1.21 +#include "nsISupportsImpl.h" // for Layer::AddRef, etc 1.22 +#include "nsRegion.h" // for nsIntRegion 1.23 + 1.24 +using namespace mozilla::gfx; 1.25 + 1.26 +namespace mozilla { 1.27 +namespace layers { 1.28 + 1.29 +class ClientImageLayer : public ImageLayer, 1.30 + public ClientLayer { 1.31 +public: 1.32 + ClientImageLayer(ClientLayerManager* aLayerManager) 1.33 + : ImageLayer(aLayerManager, 1.34 + static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST())) 1.35 + , mImageClientTypeContainer(BUFFER_UNKNOWN) 1.36 + { 1.37 + MOZ_COUNT_CTOR(ClientImageLayer); 1.38 + } 1.39 + virtual ~ClientImageLayer() 1.40 + { 1.41 + DestroyBackBuffer(); 1.42 + MOZ_COUNT_DTOR(ClientImageLayer); 1.43 + } 1.44 + 1.45 + virtual void SetContainer(ImageContainer* aContainer) MOZ_OVERRIDE 1.46 + { 1.47 + ImageLayer::SetContainer(aContainer); 1.48 + mImageClientTypeContainer = BUFFER_UNKNOWN; 1.49 + } 1.50 + 1.51 + virtual void SetVisibleRegion(const nsIntRegion& aRegion) 1.52 + { 1.53 + NS_ASSERTION(ClientManager()->InConstruction(), 1.54 + "Can only set properties in construction phase"); 1.55 + ImageLayer::SetVisibleRegion(aRegion); 1.56 + } 1.57 + 1.58 + virtual void RenderLayer(); 1.59 + 1.60 + virtual void ClearCachedResources() MOZ_OVERRIDE 1.61 + { 1.62 + DestroyBackBuffer(); 1.63 + } 1.64 + 1.65 + virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) 1.66 + { 1.67 + aAttrs = ImageLayerAttributes(mFilter, mScaleToSize, mScaleMode); 1.68 + } 1.69 + 1.70 + virtual Layer* AsLayer() { return this; } 1.71 + virtual ShadowableLayer* AsShadowableLayer() { return this; } 1.72 + 1.73 + virtual void Disconnect() 1.74 + { 1.75 + DestroyBackBuffer(); 1.76 + ClientLayer::Disconnect(); 1.77 + } 1.78 + 1.79 + void DestroyBackBuffer() 1.80 + { 1.81 + if (mImageClient) { 1.82 + mImageClient->OnDetach(); 1.83 + mImageClient = nullptr; 1.84 + } 1.85 + } 1.86 + 1.87 + virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE 1.88 + { 1.89 + return mImageClient; 1.90 + } 1.91 + 1.92 +protected: 1.93 + ClientLayerManager* ClientManager() 1.94 + { 1.95 + return static_cast<ClientLayerManager*>(mManager); 1.96 + } 1.97 + 1.98 + CompositableType GetImageClientType() 1.99 + { 1.100 + if (mImageClientTypeContainer != BUFFER_UNKNOWN) { 1.101 + return mImageClientTypeContainer; 1.102 + } 1.103 + 1.104 + if (mContainer->IsAsync()) { 1.105 + mImageClientTypeContainer = BUFFER_BRIDGE; 1.106 + return mImageClientTypeContainer; 1.107 + } 1.108 + 1.109 + RefPtr<gfx::SourceSurface> surface; 1.110 + AutoLockImage autoLock(mContainer, &surface); 1.111 + 1.112 +#ifdef MOZ_WIDGET_GONK 1.113 + // gralloc buffer needs BUFFER_IMAGE_BUFFERED to prevent 1.114 + // the buffer's usage conflict. 1.115 + mImageClientTypeContainer = autoLock.GetImage() ? 1.116 + BUFFER_IMAGE_BUFFERED : BUFFER_UNKNOWN; 1.117 +#else 1.118 + mImageClientTypeContainer = autoLock.GetImage() ? 1.119 + BUFFER_IMAGE_SINGLE : BUFFER_UNKNOWN; 1.120 +#endif 1.121 + return mImageClientTypeContainer; 1.122 + } 1.123 + 1.124 + RefPtr<ImageClient> mImageClient; 1.125 + CompositableType mImageClientTypeContainer; 1.126 +}; 1.127 + 1.128 +void 1.129 +ClientImageLayer::RenderLayer() 1.130 +{ 1.131 + if (GetMaskLayer()) { 1.132 + ToClientLayer(GetMaskLayer())->RenderLayer(); 1.133 + } 1.134 + 1.135 + if (!mContainer) { 1.136 + return; 1.137 + } 1.138 + 1.139 + if (mImageClient) { 1.140 + mImageClient->OnTransaction(); 1.141 + } 1.142 + 1.143 + if (!mImageClient || 1.144 + !mImageClient->UpdateImage(mContainer, GetContentFlags())) { 1.145 + CompositableType type = GetImageClientType(); 1.146 + if (type == BUFFER_UNKNOWN) { 1.147 + return; 1.148 + } 1.149 + TextureFlags flags = TEXTURE_FRONT; 1.150 + if (mDisallowBigImage) { 1.151 + flags |= TEXTURE_DISALLOW_BIGIMAGE; 1.152 + } 1.153 + mImageClient = ImageClient::CreateImageClient(type, 1.154 + ClientManager()->AsShadowForwarder(), 1.155 + flags); 1.156 + if (type == BUFFER_BRIDGE) { 1.157 + static_cast<ImageClientBridge*>(mImageClient.get())->SetLayer(this); 1.158 + } 1.159 + 1.160 + if (!mImageClient) { 1.161 + return; 1.162 + } 1.163 + if (HasShadow() && !mContainer->IsAsync()) { 1.164 + mImageClient->Connect(); 1.165 + ClientManager()->AsShadowForwarder()->Attach(mImageClient, this); 1.166 + } 1.167 + if (!mImageClient->UpdateImage(mContainer, GetContentFlags())) { 1.168 + return; 1.169 + } 1.170 + } 1.171 + if (mImageClient) { 1.172 + mImageClient->OnTransaction(); 1.173 + } 1.174 + ClientManager()->Hold(this); 1.175 +} 1.176 + 1.177 +already_AddRefed<ImageLayer> 1.178 +ClientLayerManager::CreateImageLayer() 1.179 +{ 1.180 + NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); 1.181 + nsRefPtr<ClientImageLayer> layer = 1.182 + new ClientImageLayer(this); 1.183 + CREATE_SHADOW(Image); 1.184 + return layer.forget(); 1.185 +} 1.186 +} 1.187 +}