1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/composite/ImageHost.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,226 @@ 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 +#include "ImageHost.h" 1.10 +#include "LayersLogging.h" // for AppendToString 1.11 +#include "composite/CompositableHost.h" // for CompositableHost, etc 1.12 +#include "ipc/IPCMessageUtils.h" // for null_t 1.13 +#include "mozilla/layers/Compositor.h" // for Compositor 1.14 +#include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc 1.15 +#include "nsAString.h" 1.16 +#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION 1.17 +#include "nsPrintfCString.h" // for nsPrintfCString 1.18 +#include "nsString.h" // for nsAutoCString 1.19 + 1.20 +class nsIntRegion; 1.21 + 1.22 +namespace mozilla { 1.23 +namespace gfx { 1.24 +class Matrix4x4; 1.25 +} 1.26 + 1.27 +using namespace gfx; 1.28 + 1.29 +namespace layers { 1.30 + 1.31 +class ISurfaceAllocator; 1.32 + 1.33 +ImageHost::ImageHost(const TextureInfo& aTextureInfo) 1.34 + : CompositableHost(aTextureInfo) 1.35 + , mFrontBuffer(nullptr) 1.36 + , mHasPictureRect(false) 1.37 +{} 1.38 + 1.39 +ImageHost::~ImageHost() {} 1.40 + 1.41 +void 1.42 +ImageHost::UseTextureHost(TextureHost* aTexture) 1.43 +{ 1.44 + CompositableHost::UseTextureHost(aTexture); 1.45 + mFrontBuffer = aTexture; 1.46 +} 1.47 + 1.48 +void 1.49 +ImageHost::RemoveTextureHost(TextureHost* aTexture) 1.50 +{ 1.51 + CompositableHost::RemoveTextureHost(aTexture); 1.52 + if (aTexture && mFrontBuffer == aTexture) { 1.53 + aTexture->SetCompositableBackendSpecificData(nullptr); 1.54 + mFrontBuffer = nullptr; 1.55 + } 1.56 +} 1.57 + 1.58 +TextureHost* 1.59 +ImageHost::GetAsTextureHost() 1.60 +{ 1.61 + return mFrontBuffer; 1.62 +} 1.63 + 1.64 +void 1.65 +ImageHost::Composite(EffectChain& aEffectChain, 1.66 + float aOpacity, 1.67 + const gfx::Matrix4x4& aTransform, 1.68 + const gfx::Filter& aFilter, 1.69 + const gfx::Rect& aClipRect, 1.70 + const nsIntRegion* aVisibleRegion, 1.71 + TiledLayerProperties* aLayerProperties) 1.72 +{ 1.73 + if (!GetCompositor()) { 1.74 + // should only happen when a tab is dragged to another window and 1.75 + // async-video is still sending frames but we haven't attached the 1.76 + // set the new compositor yet. 1.77 + return; 1.78 + } 1.79 + if (!mFrontBuffer) { 1.80 + return; 1.81 + } 1.82 + 1.83 + // Make sure the front buffer has a compositor 1.84 + mFrontBuffer->SetCompositor(GetCompositor()); 1.85 + mFrontBuffer->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData()); 1.86 + 1.87 + AutoLockTextureHost autoLock(mFrontBuffer); 1.88 + if (autoLock.Failed()) { 1.89 + NS_WARNING("failed to lock front buffer"); 1.90 + return; 1.91 + } 1.92 + RefPtr<NewTextureSource> source = mFrontBuffer->GetTextureSources(); 1.93 + if (!source) { 1.94 + return; 1.95 + } 1.96 + RefPtr<TexturedEffect> effect = CreateTexturedEffect(mFrontBuffer->GetFormat(), 1.97 + source, 1.98 + aFilter); 1.99 + if (!effect) { 1.100 + return; 1.101 + } 1.102 + 1.103 + aEffectChain.mPrimaryEffect = effect; 1.104 + IntSize textureSize = source->GetSize(); 1.105 + gfx::Rect gfxPictureRect 1.106 + = mHasPictureRect ? gfx::Rect(0, 0, mPictureRect.width, mPictureRect.height) 1.107 + : gfx::Rect(0, 0, textureSize.width, textureSize.height); 1.108 + 1.109 + gfx::Rect pictureRect(0, 0, 1.110 + mPictureRect.width, 1.111 + mPictureRect.height); 1.112 + //XXX: We might have multiple texture sources here (e.g. 3 YCbCr textures), and we're 1.113 + // only iterating over the tiles of the first one. Are we assuming that the tiling 1.114 + // will be identical? Can we ensure that somehow? 1.115 + TileIterator* it = source->AsTileIterator(); 1.116 + if (it) { 1.117 + it->BeginTileIteration(); 1.118 + do { 1.119 + nsIntRect tileRect = it->GetTileRect(); 1.120 + gfx::Rect rect(tileRect.x, tileRect.y, tileRect.width, tileRect.height); 1.121 + if (mHasPictureRect) { 1.122 + rect = rect.Intersect(pictureRect); 1.123 + effect->mTextureCoords = Rect(Float(rect.x - tileRect.x)/ tileRect.width, 1.124 + Float(rect.y - tileRect.y) / tileRect.height, 1.125 + Float(rect.width) / tileRect.width, 1.126 + Float(rect.height) / tileRect.height); 1.127 + } else { 1.128 + effect->mTextureCoords = Rect(0, 0, 1, 1); 1.129 + } 1.130 + GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain, 1.131 + aOpacity, aTransform); 1.132 + GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE|DIAGNOSTIC_BIGIMAGE, 1.133 + rect, aClipRect, aTransform, mFlashCounter); 1.134 + } while (it->NextTile()); 1.135 + it->EndTileIteration(); 1.136 + // layer border 1.137 + GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE, 1.138 + gfxPictureRect, aClipRect, 1.139 + aTransform, mFlashCounter); 1.140 + } else { 1.141 + IntSize textureSize = source->GetSize(); 1.142 + gfx::Rect rect; 1.143 + if (mHasPictureRect) { 1.144 + effect->mTextureCoords = Rect(Float(mPictureRect.x) / textureSize.width, 1.145 + Float(mPictureRect.y) / textureSize.height, 1.146 + Float(mPictureRect.width) / textureSize.width, 1.147 + Float(mPictureRect.height) / textureSize.height); 1.148 + rect = pictureRect; 1.149 + } else { 1.150 + effect->mTextureCoords = Rect(0, 0, 1, 1); 1.151 + rect = gfx::Rect(0, 0, textureSize.width, textureSize.height); 1.152 + } 1.153 + 1.154 + if (mFrontBuffer->GetFlags() & TEXTURE_NEEDS_Y_FLIP) { 1.155 + effect->mTextureCoords.y = effect->mTextureCoords.YMost(); 1.156 + effect->mTextureCoords.height = -effect->mTextureCoords.height; 1.157 + } 1.158 + 1.159 + GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain, 1.160 + aOpacity, aTransform); 1.161 + GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE, 1.162 + rect, aClipRect, 1.163 + aTransform, mFlashCounter); 1.164 + } 1.165 +} 1.166 + 1.167 +void 1.168 +ImageHost::SetCompositor(Compositor* aCompositor) 1.169 +{ 1.170 + if (mFrontBuffer && mCompositor != aCompositor) { 1.171 + mFrontBuffer->SetCompositor(aCompositor); 1.172 + } 1.173 + CompositableHost::SetCompositor(aCompositor); 1.174 +} 1.175 + 1.176 +void 1.177 +ImageHost::PrintInfo(nsACString& aTo, const char* aPrefix) 1.178 +{ 1.179 + aTo += aPrefix; 1.180 + aTo += nsPrintfCString("ImageHost (0x%p)", this); 1.181 + 1.182 + AppendToString(aTo, mPictureRect, " [picture-rect=", "]"); 1.183 + 1.184 + if (mFrontBuffer) { 1.185 + nsAutoCString pfx(aPrefix); 1.186 + pfx += " "; 1.187 + aTo += "\n"; 1.188 + mFrontBuffer->PrintInfo(aTo, pfx.get()); 1.189 + } 1.190 +} 1.191 + 1.192 +#ifdef MOZ_DUMP_PAINTING 1.193 +void 1.194 +ImageHost::Dump(FILE* aFile, 1.195 + const char* aPrefix, 1.196 + bool aDumpHtml) 1.197 +{ 1.198 + if (!aFile) { 1.199 + aFile = stderr; 1.200 + } 1.201 + if (mFrontBuffer) { 1.202 + fprintf_stderr(aFile, "%s", aPrefix); 1.203 + fprintf_stderr(aFile, aDumpHtml ? "<ul><li>TextureHost: " 1.204 + : "TextureHost: "); 1.205 + DumpTextureHost(aFile, mFrontBuffer); 1.206 + fprintf_stderr(aFile, aDumpHtml ? " </li></ul> " : " "); 1.207 + } 1.208 +} 1.209 +#endif 1.210 + 1.211 +LayerRenderState 1.212 +ImageHost::GetRenderState() 1.213 +{ 1.214 + if (mFrontBuffer) { 1.215 + return mFrontBuffer->GetRenderState(); 1.216 + } 1.217 + return LayerRenderState(); 1.218 +} 1.219 + 1.220 +#ifdef MOZ_DUMP_PAINTING 1.221 +TemporaryRef<gfx::DataSourceSurface> 1.222 +ImageHost::GetAsSurface() 1.223 +{ 1.224 + return mFrontBuffer->GetAsSurface(); 1.225 +} 1.226 +#endif 1.227 + 1.228 +} 1.229 +}