gfx/layers/ReadbackLayer.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/layers/ReadbackLayer.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,201 @@
     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_READBACKLAYER_H
    1.10 +#define GFX_READBACKLAYER_H
    1.11 +
    1.12 +#include <stdint.h>                     // for uint64_t
    1.13 +#include "Layers.h"                     // for Layer, etc
    1.14 +#include "gfxColor.h"                   // for gfxRGBA
    1.15 +#include "gfxRect.h"                    // for gfxRect
    1.16 +#include "mozilla/mozalloc.h"           // for operator delete
    1.17 +#include "nsAutoPtr.h"                  // for nsAutoPtr
    1.18 +#include "nsCOMPtr.h"                   // for already_AddRefed
    1.19 +#include "nsDebug.h"                    // for NS_ASSERTION
    1.20 +#include "nsPoint.h"                    // for nsIntPoint
    1.21 +#include "nsRect.h"                     // for nsIntRect
    1.22 +#include "nsSize.h"                     // for nsIntSize
    1.23 +#include "nscore.h"                     // for nsACString
    1.24 +
    1.25 +class gfxContext;
    1.26 +
    1.27 +namespace mozilla {
    1.28 +namespace layers {
    1.29 +
    1.30 +class ReadbackProcessor;
    1.31 +
    1.32 +/**
    1.33 + * A ReadbackSink receives a stream of updates to a rectangle of pixels.
    1.34 + * These update callbacks are always called on the main thread, either during
    1.35 + * EndTransaction or from the event loop.
    1.36 + */
    1.37 +class ReadbackSink {
    1.38 +public:
    1.39 +  ReadbackSink() {}
    1.40 +  virtual ~ReadbackSink() {}
    1.41 +
    1.42 +  /**
    1.43 +   * Sends an update to indicate that the background is currently unknown.
    1.44 +   */
    1.45 +  virtual void SetUnknown(uint64_t aSequenceNumber) = 0;
    1.46 +  /**
    1.47 +   * Called by the layer system to indicate that the contents of part of
    1.48 +   * the readback area are changing.
    1.49 +   * @param aRect is the rectangle of content that is being updated,
    1.50 +   * in the coordinate system of the ReadbackLayer.
    1.51 +   * @param aSequenceNumber updates issued out of order should be ignored.
    1.52 +   * Only use updates whose sequence counter is greater than all other updates
    1.53 +   * seen so far. Return null when a non-fresh sequence value is given.
    1.54 +   * @return a context into which the update should be drawn. This should be
    1.55 +   * set up to clip to aRect. Zero should never be passed as a sequence number.
    1.56 +   * If this returns null, EndUpdate should NOT be called. If it returns
    1.57 +   * non-null, EndUpdate must be called.
    1.58 +   *
    1.59 +   * We don't support partially unknown backgrounds. Therefore, the
    1.60 +   * first BeginUpdate after a SetUnknown will have the complete background.
    1.61 +   */
    1.62 +  virtual already_AddRefed<gfxContext>
    1.63 +      BeginUpdate(const nsIntRect& aRect, uint64_t aSequenceNumber) = 0;
    1.64 +  /**
    1.65 +   * EndUpdate must be called immediately after BeginUpdate, without returning
    1.66 +   * to the event loop.
    1.67 +   * @param aContext the context returned by BeginUpdate
    1.68 +   * Implicitly Restore()s the state of aContext.
    1.69 +   */
    1.70 +  virtual void EndUpdate(gfxContext* aContext, const nsIntRect& aRect) = 0;
    1.71 +};
    1.72 +
    1.73 +/**
    1.74 + * A ReadbackLayer never renders anything. It enables clients to extract
    1.75 + * the rendered contents of the layer tree below the ReadbackLayer.
    1.76 + * The rendered contents are delivered asynchronously via calls to a
    1.77 + * ReadbackSink object supplied by the client.
    1.78 + *
    1.79 + * This is a "best effort" API; it is possible for the layer system to tell
    1.80 + * the ReadbackSink that the contents of the readback area are unknown.
    1.81 + *
    1.82 + * This API exists to work around the limitations of transparent windowless
    1.83 + * plugin rendering APIs. It should not be used for anything else.
    1.84 + */
    1.85 +class ReadbackLayer : public Layer {
    1.86 +public:
    1.87 +  MOZ_LAYER_DECL_NAME("ReadbackLayer", TYPE_READBACK)
    1.88 +
    1.89 +  virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
    1.90 +  {
    1.91 +    // Snap our local transform first, and snap the inherited transform as well.
    1.92 +    // This makes our snapping equivalent to what would happen if our content
    1.93 +    // was drawn into a ThebesLayer (gfxContext would snap using the local
    1.94 +    // transform, then we'd snap again when compositing the ThebesLayer).
    1.95 +    mEffectiveTransform =
    1.96 +        SnapTransform(GetLocalTransform(), gfxRect(0, 0, mSize.width, mSize.height),
    1.97 +                      nullptr)*
    1.98 +        SnapTransformTranslation(aTransformToSurface, nullptr);
    1.99 +  }
   1.100 +
   1.101 +  /**
   1.102 +   * CONSTRUCTION PHASE ONLY
   1.103 +   * Set the callback object to which readback updates will be delivered.
   1.104 +   * This also resets the "needed rectangle" so that on the next layer tree
   1.105 +   * transaction we will try to deliver the full contents of the readback
   1.106 +   * area to the sink.
   1.107 +   * This layer takes ownership of the sink. It will be deleted when the
   1.108 +   * layer is destroyed or when a new sink is set.
   1.109 +   * Initially the contents of the readback area are completely unknown.
   1.110 +   */
   1.111 +  void SetSink(ReadbackSink* aSink)
   1.112 +  {
   1.113 +    SetUnknown();
   1.114 +    mSink = aSink;
   1.115 +  }
   1.116 +  ReadbackSink* GetSink() { return mSink; }
   1.117 +
   1.118 +  /**
   1.119 +   * CONSTRUCTION PHASE ONLY
   1.120 +   * Set the size of content that should be read back. The readback area
   1.121 +   * has its top-left at 0,0 and has size aSize.
   1.122 +   * Can only be called while the sink is null!
   1.123 +   */
   1.124 +  void SetSize(const nsIntSize& aSize)
   1.125 +  {
   1.126 +    NS_ASSERTION(!mSink, "Should have no sink while changing size!");
   1.127 +    mSize = aSize;
   1.128 +  }
   1.129 +  const nsIntSize& GetSize() { return mSize; }
   1.130 +  nsIntRect GetRect() { return nsIntRect(nsIntPoint(0, 0), mSize); }
   1.131 +
   1.132 +  bool IsBackgroundKnown()
   1.133 +  {
   1.134 +    return mBackgroundLayer || mBackgroundColor.a == 1.0;
   1.135 +  }
   1.136 +
   1.137 +  void NotifyRemoved() {
   1.138 +    SetUnknown();
   1.139 +    mSink = nullptr;
   1.140 +  }
   1.141 +
   1.142 +  void NotifyThebesLayerRemoved(ThebesLayer* aLayer)
   1.143 +  {
   1.144 +    if (mBackgroundLayer == aLayer) {
   1.145 +      mBackgroundLayer = nullptr;
   1.146 +    }
   1.147 +  }
   1.148 +
   1.149 +  const nsIntPoint& GetBackgroundLayerOffset() { return mBackgroundLayerOffset; }
   1.150 +
   1.151 +  uint64_t AllocateSequenceNumber() { return ++mSequenceCounter; }
   1.152 +
   1.153 +  void SetUnknown()
   1.154 +  {
   1.155 +    if (IsBackgroundKnown()) {
   1.156 +      if (mSink) {
   1.157 +        mSink->SetUnknown(AllocateSequenceNumber());
   1.158 +      }
   1.159 +      mBackgroundLayer = nullptr;
   1.160 +      mBackgroundColor = gfxRGBA(0,0,0,0);
   1.161 +    }
   1.162 +  }
   1.163 +
   1.164 +protected:
   1.165 +  friend class ReadbackProcessor;
   1.166 +
   1.167 +  ReadbackLayer(LayerManager* aManager, void* aImplData) :
   1.168 +    Layer(aManager, aImplData),
   1.169 +    mSequenceCounter(0),
   1.170 +    mSize(0,0),
   1.171 +    mBackgroundLayer(nullptr),
   1.172 +    mBackgroundLayerOffset(0, 0),
   1.173 +    mBackgroundColor(gfxRGBA(0,0,0,0))
   1.174 +  {}
   1.175 +
   1.176 +  // Print interesting information about this into aTo.  Internally
   1.177 +  // used to implement Dump*() and Log*().
   1.178 +  virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
   1.179 +
   1.180 +  uint64_t mSequenceCounter;
   1.181 +  nsAutoPtr<ReadbackSink> mSink;
   1.182 +  nsIntSize mSize;
   1.183 +
   1.184 +  // This can refer to any (earlier) sibling ThebesLayer. That ThebesLayer
   1.185 +  // must have mUsedForReadback set on it. If the ThebesLayer is removed
   1.186 +  // for the container, this will be set to null by NotifyThebesLayerRemoved.
   1.187 +  // This ThebesLayer contains the contents which have previously been reported
   1.188 +  // to mSink. The ThebesLayer had only an integer translation transform,
   1.189 +  // and it covered the entire readback area. This layer also had only an
   1.190 +  // integer translation transform.
   1.191 +  ThebesLayer* mBackgroundLayer;
   1.192 +  // When mBackgroundLayer is non-null, this is the offset to add to
   1.193 +  // convert from the coordinates of mBackgroundLayer to the coordinates
   1.194 +  // of this layer.
   1.195 +  nsIntPoint   mBackgroundLayerOffset;
   1.196 +  // When mBackgroundColor is opaque, this is the color of the ColorLayer
   1.197 +  // that contained the contents we reported to mSink, which covered the
   1.198 +  // entire readback area.
   1.199 +  gfxRGBA      mBackgroundColor;
   1.200 +};
   1.201 +
   1.202 +}
   1.203 +}
   1.204 +#endif /* GFX_READBACKLAYER_H */

mercurial