gfx/layers/composite/ImageHost.cpp

changeset 0
6474c204b198
     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 +}

mercurial