author Robert O'Callahan <>
Mon, 28 Mar 2011 12:59:47 +1300
changeset 63981 d9c2c2e76a37a8f6f5c337e7a445dd4a9ec4d197
parent 57631 941c3d14e14d11a7b2f4160d5190471a11f8b820
child 64162 8c373f9e40569a81d1f8c34a73c3fd8e86814fa8
permissions -rw-r--r--
Bug 622072. Part 3: Support empty transactions for canvas layers. r=tnikkel The basic idea is that whenever a layer transaction updates the window, we clear out the invalidation state for the canvas rendering context, using a DidTransactionCallback registered on the layer(s) for the canvas, which calls MakeContextClean. The DidTransactionCallbacks are directed to the user data attached to the Layer, which holds a strong reference to the canvas element. This ensures that the element lives as long as the layer. Layers are destroyed when the presentation is torn down (including if the frame is destroyed), so we can't have a leak here. The reference to the canvas element is only strong because the layer might briefly outlive the frame (the layer won't be destroyed until the next paint of the window). This patch moves responsibility for calling CanvasLayer::Updated and nsFrame::MarkLayersActive from the canvas context to nsHTMLCanvasElement::InvalidateFrame. We call Updated on the retained CanvasLayer, if there is one; any other CanvasLayers created for this canvas would only be used once, and have Updated called on them in BuildLayer when created.

/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 * The Original Code is code.
 * The Initial Developer of the Original Code is
 *   Vladimir Vukicevic <>
 * Portions created by the Initial Developer are Copyright (C) 2005
 * the Initial Developer. All Rights Reserved.
 * Contributor(s):
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * ***** END LICENSE BLOCK ***** */

#ifndef nsICanvasRenderingContextInternal_h___
#define nsICanvasRenderingContextInternal_h___

#include "nsISupports.h"
#include "nsIInputStream.h"
#include "nsIDocShell.h"
#include "gfxPattern.h"

{ 0xffb42d3c, 0x8281, 0x44c8, \
  { 0xac, 0xba, 0x73, 0x15, 0x31, 0xaa, 0xe5, 0x07 } }

class nsHTMLCanvasElement;
class gfxContext;
class gfxASurface;
class nsIPropertyBag;
class nsDisplayListBuilder;

namespace mozilla {
namespace layers {
class CanvasLayer;
class LayerManager;
namespace ipc {
class Shmem;

class nsICanvasRenderingContextInternal : public nsISupports {
  typedef mozilla::layers::CanvasLayer CanvasLayer;
  typedef mozilla::layers::LayerManager LayerManager;


  // This method should NOT hold a ref to aParentCanvas; it will be called
  // with nsnull when the element is going away.
  NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas) = 0;

  // Sets the dimensions of the canvas, in pixels.  Called
  // whenever the size of the element changes.
  NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height) = 0;

  NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, PRInt32 width, PRInt32 height) = 0;

  // Render the canvas at the origin of the given gfxContext
  NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter) = 0;

  // Gives you a stream containing the image represented by this context.
  // The format is given in aMimeTime, for example "image/png".
  // If the image format does not support transparency or aIncludeTransparency
  // is false, alpha will be discarded and the result will be the image
  // composited on black.
  NS_IMETHOD GetInputStream(const char *aMimeType,
                            const PRUnichar *aEncoderOptions,
                            nsIInputStream **aStream) = 0;

  // If this canvas context can be represented with a simple Thebes surface,
  // return the surface.  Otherwise returns an error.
  NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0;

  // If this context is opaque, the backing store of the canvas should
  // be created as opaque; all compositing operators should assume the
  // dst alpha is always 1.0.  If this is never called, the context
  // defaults to false (not opaque).
  NS_IMETHOD SetIsOpaque(PRBool isOpaque) = 0;

  // Invalidate this context and release any held resources, in preperation
  // for possibly reinitializing with SetDimensions/InitializeWithSurface.
  NS_IMETHOD Reset() = 0;

  // Return the CanvasLayer for this context, creating
  // one for the given layer manager if not available.
  virtual already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                       CanvasLayer *aOldLayer,
                                                       LayerManager *aManager) = 0;

  virtual void MarkContextClean() = 0;

  // Redraw the dirty rectangle of this canvas.
  NS_IMETHOD Redraw(const gfxRect &dirty) = 0;

  // Passes a generic nsIPropertyBag options argument, along with the
  // previous one, if any.  Optional.
  NS_IMETHOD SetContextOptions(nsIPropertyBag *aNewOptions) { return NS_OK; }

  // shmem support

  // If this context can be set to use Mozilla's Shmem segments as its backing
  // store, this will set it to that state. Note that if you have drawn
  // anything into this canvas before changing the shmem state, it will be
  // lost.
  NS_IMETHOD SetIsIPC(PRBool isIPC) = 0;


#endif /* nsICanvasRenderingContextInternal_h___ */