gfx/layers/composite/ImageHost.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "ImageHost.h"
michael@0 7 #include "LayersLogging.h" // for AppendToString
michael@0 8 #include "composite/CompositableHost.h" // for CompositableHost, etc
michael@0 9 #include "ipc/IPCMessageUtils.h" // for null_t
michael@0 10 #include "mozilla/layers/Compositor.h" // for Compositor
michael@0 11 #include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
michael@0 12 #include "nsAString.h"
michael@0 13 #include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
michael@0 14 #include "nsPrintfCString.h" // for nsPrintfCString
michael@0 15 #include "nsString.h" // for nsAutoCString
michael@0 16
michael@0 17 class nsIntRegion;
michael@0 18
michael@0 19 namespace mozilla {
michael@0 20 namespace gfx {
michael@0 21 class Matrix4x4;
michael@0 22 }
michael@0 23
michael@0 24 using namespace gfx;
michael@0 25
michael@0 26 namespace layers {
michael@0 27
michael@0 28 class ISurfaceAllocator;
michael@0 29
michael@0 30 ImageHost::ImageHost(const TextureInfo& aTextureInfo)
michael@0 31 : CompositableHost(aTextureInfo)
michael@0 32 , mFrontBuffer(nullptr)
michael@0 33 , mHasPictureRect(false)
michael@0 34 {}
michael@0 35
michael@0 36 ImageHost::~ImageHost() {}
michael@0 37
michael@0 38 void
michael@0 39 ImageHost::UseTextureHost(TextureHost* aTexture)
michael@0 40 {
michael@0 41 CompositableHost::UseTextureHost(aTexture);
michael@0 42 mFrontBuffer = aTexture;
michael@0 43 }
michael@0 44
michael@0 45 void
michael@0 46 ImageHost::RemoveTextureHost(TextureHost* aTexture)
michael@0 47 {
michael@0 48 CompositableHost::RemoveTextureHost(aTexture);
michael@0 49 if (aTexture && mFrontBuffer == aTexture) {
michael@0 50 aTexture->SetCompositableBackendSpecificData(nullptr);
michael@0 51 mFrontBuffer = nullptr;
michael@0 52 }
michael@0 53 }
michael@0 54
michael@0 55 TextureHost*
michael@0 56 ImageHost::GetAsTextureHost()
michael@0 57 {
michael@0 58 return mFrontBuffer;
michael@0 59 }
michael@0 60
michael@0 61 void
michael@0 62 ImageHost::Composite(EffectChain& aEffectChain,
michael@0 63 float aOpacity,
michael@0 64 const gfx::Matrix4x4& aTransform,
michael@0 65 const gfx::Filter& aFilter,
michael@0 66 const gfx::Rect& aClipRect,
michael@0 67 const nsIntRegion* aVisibleRegion,
michael@0 68 TiledLayerProperties* aLayerProperties)
michael@0 69 {
michael@0 70 if (!GetCompositor()) {
michael@0 71 // should only happen when a tab is dragged to another window and
michael@0 72 // async-video is still sending frames but we haven't attached the
michael@0 73 // set the new compositor yet.
michael@0 74 return;
michael@0 75 }
michael@0 76 if (!mFrontBuffer) {
michael@0 77 return;
michael@0 78 }
michael@0 79
michael@0 80 // Make sure the front buffer has a compositor
michael@0 81 mFrontBuffer->SetCompositor(GetCompositor());
michael@0 82 mFrontBuffer->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
michael@0 83
michael@0 84 AutoLockTextureHost autoLock(mFrontBuffer);
michael@0 85 if (autoLock.Failed()) {
michael@0 86 NS_WARNING("failed to lock front buffer");
michael@0 87 return;
michael@0 88 }
michael@0 89 RefPtr<NewTextureSource> source = mFrontBuffer->GetTextureSources();
michael@0 90 if (!source) {
michael@0 91 return;
michael@0 92 }
michael@0 93 RefPtr<TexturedEffect> effect = CreateTexturedEffect(mFrontBuffer->GetFormat(),
michael@0 94 source,
michael@0 95 aFilter);
michael@0 96 if (!effect) {
michael@0 97 return;
michael@0 98 }
michael@0 99
michael@0 100 aEffectChain.mPrimaryEffect = effect;
michael@0 101 IntSize textureSize = source->GetSize();
michael@0 102 gfx::Rect gfxPictureRect
michael@0 103 = mHasPictureRect ? gfx::Rect(0, 0, mPictureRect.width, mPictureRect.height)
michael@0 104 : gfx::Rect(0, 0, textureSize.width, textureSize.height);
michael@0 105
michael@0 106 gfx::Rect pictureRect(0, 0,
michael@0 107 mPictureRect.width,
michael@0 108 mPictureRect.height);
michael@0 109 //XXX: We might have multiple texture sources here (e.g. 3 YCbCr textures), and we're
michael@0 110 // only iterating over the tiles of the first one. Are we assuming that the tiling
michael@0 111 // will be identical? Can we ensure that somehow?
michael@0 112 TileIterator* it = source->AsTileIterator();
michael@0 113 if (it) {
michael@0 114 it->BeginTileIteration();
michael@0 115 do {
michael@0 116 nsIntRect tileRect = it->GetTileRect();
michael@0 117 gfx::Rect rect(tileRect.x, tileRect.y, tileRect.width, tileRect.height);
michael@0 118 if (mHasPictureRect) {
michael@0 119 rect = rect.Intersect(pictureRect);
michael@0 120 effect->mTextureCoords = Rect(Float(rect.x - tileRect.x)/ tileRect.width,
michael@0 121 Float(rect.y - tileRect.y) / tileRect.height,
michael@0 122 Float(rect.width) / tileRect.width,
michael@0 123 Float(rect.height) / tileRect.height);
michael@0 124 } else {
michael@0 125 effect->mTextureCoords = Rect(0, 0, 1, 1);
michael@0 126 }
michael@0 127 GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain,
michael@0 128 aOpacity, aTransform);
michael@0 129 GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE|DIAGNOSTIC_BIGIMAGE,
michael@0 130 rect, aClipRect, aTransform, mFlashCounter);
michael@0 131 } while (it->NextTile());
michael@0 132 it->EndTileIteration();
michael@0 133 // layer border
michael@0 134 GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE,
michael@0 135 gfxPictureRect, aClipRect,
michael@0 136 aTransform, mFlashCounter);
michael@0 137 } else {
michael@0 138 IntSize textureSize = source->GetSize();
michael@0 139 gfx::Rect rect;
michael@0 140 if (mHasPictureRect) {
michael@0 141 effect->mTextureCoords = Rect(Float(mPictureRect.x) / textureSize.width,
michael@0 142 Float(mPictureRect.y) / textureSize.height,
michael@0 143 Float(mPictureRect.width) / textureSize.width,
michael@0 144 Float(mPictureRect.height) / textureSize.height);
michael@0 145 rect = pictureRect;
michael@0 146 } else {
michael@0 147 effect->mTextureCoords = Rect(0, 0, 1, 1);
michael@0 148 rect = gfx::Rect(0, 0, textureSize.width, textureSize.height);
michael@0 149 }
michael@0 150
michael@0 151 if (mFrontBuffer->GetFlags() & TEXTURE_NEEDS_Y_FLIP) {
michael@0 152 effect->mTextureCoords.y = effect->mTextureCoords.YMost();
michael@0 153 effect->mTextureCoords.height = -effect->mTextureCoords.height;
michael@0 154 }
michael@0 155
michael@0 156 GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain,
michael@0 157 aOpacity, aTransform);
michael@0 158 GetCompositor()->DrawDiagnostics(DIAGNOSTIC_IMAGE,
michael@0 159 rect, aClipRect,
michael@0 160 aTransform, mFlashCounter);
michael@0 161 }
michael@0 162 }
michael@0 163
michael@0 164 void
michael@0 165 ImageHost::SetCompositor(Compositor* aCompositor)
michael@0 166 {
michael@0 167 if (mFrontBuffer && mCompositor != aCompositor) {
michael@0 168 mFrontBuffer->SetCompositor(aCompositor);
michael@0 169 }
michael@0 170 CompositableHost::SetCompositor(aCompositor);
michael@0 171 }
michael@0 172
michael@0 173 void
michael@0 174 ImageHost::PrintInfo(nsACString& aTo, const char* aPrefix)
michael@0 175 {
michael@0 176 aTo += aPrefix;
michael@0 177 aTo += nsPrintfCString("ImageHost (0x%p)", this);
michael@0 178
michael@0 179 AppendToString(aTo, mPictureRect, " [picture-rect=", "]");
michael@0 180
michael@0 181 if (mFrontBuffer) {
michael@0 182 nsAutoCString pfx(aPrefix);
michael@0 183 pfx += " ";
michael@0 184 aTo += "\n";
michael@0 185 mFrontBuffer->PrintInfo(aTo, pfx.get());
michael@0 186 }
michael@0 187 }
michael@0 188
michael@0 189 #ifdef MOZ_DUMP_PAINTING
michael@0 190 void
michael@0 191 ImageHost::Dump(FILE* aFile,
michael@0 192 const char* aPrefix,
michael@0 193 bool aDumpHtml)
michael@0 194 {
michael@0 195 if (!aFile) {
michael@0 196 aFile = stderr;
michael@0 197 }
michael@0 198 if (mFrontBuffer) {
michael@0 199 fprintf_stderr(aFile, "%s", aPrefix);
michael@0 200 fprintf_stderr(aFile, aDumpHtml ? "<ul><li>TextureHost: "
michael@0 201 : "TextureHost: ");
michael@0 202 DumpTextureHost(aFile, mFrontBuffer);
michael@0 203 fprintf_stderr(aFile, aDumpHtml ? " </li></ul> " : " ");
michael@0 204 }
michael@0 205 }
michael@0 206 #endif
michael@0 207
michael@0 208 LayerRenderState
michael@0 209 ImageHost::GetRenderState()
michael@0 210 {
michael@0 211 if (mFrontBuffer) {
michael@0 212 return mFrontBuffer->GetRenderState();
michael@0 213 }
michael@0 214 return LayerRenderState();
michael@0 215 }
michael@0 216
michael@0 217 #ifdef MOZ_DUMP_PAINTING
michael@0 218 TemporaryRef<gfx::DataSourceSurface>
michael@0 219 ImageHost::GetAsSurface()
michael@0 220 {
michael@0 221 return mFrontBuffer->GetAsSurface();
michael@0 222 }
michael@0 223 #endif
michael@0 224
michael@0 225 }
michael@0 226 }

mercurial