image/ImgDrawResult.h
author Kartikaya Gupta <kgupta@mozilla.com>
Wed, 30 May 2018 15:54:50 -0400
changeset 420571 8a1bdb8d8bf5a1c8869bf3f82fd86c56f9f4b72c
parent 396187 4e2cf0afd644cc0f2dfb0f6def3f1c1d25a19d27
child 431442 69a4c2a0aac6e8bfc041a82b634611e1432af36b
permissions -rw-r--r--
Bug 1457590 - Strengthen the contract around recycling HitTestingTreeNodes. r=botond This patch makes three related changes: - A non-functional change that factors a IsRecyclable function on HitTestingTreeNode. - A non-functional change that sprinkles proof-of-tree-lock arguments to a few HitTestingTreeNode functions, to ensure at compile-time that they can only be called while holding the tree lock. - A functional change that stops clearing mLayersId in HitTestingTreeNode::Destroy, so that if a node is non-recyclable, and it gets Destroy()'d while other code still has a RefPtr to it, that other code can still read the layers id off in a safe manner. These changes provide a stronger set of checks around node recycling, and allows for a safe mechanism to use a HitTestingTreeNode on the controller thread without having to lock the entire APZ tree. The mechanism is effectively a per-node lock, which will be added in the next patch. MozReview-Commit-ID: DBIjFDZJwhE

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_image_ImgDrawResult_h
#define mozilla_image_ImgDrawResult_h

#include <cstdint> // for uint8_t
#include "mozilla/Attributes.h"
#include "mozilla/Likely.h"

namespace mozilla {
namespace image {

/**
 * An enumeration representing the result of a drawing operation.
 *
 * Most users of ImgDrawResult will only be interested in whether the value is
 * SUCCESS or not. The other values are primarily useful for debugging and error
 * handling.
 *
 * SUCCESS: We successfully drew a completely decoded frame of the requested
 * size. Drawing again with FLAG_SYNC_DECODE would not change the result.
 *
 * INCOMPLETE: We successfully drew a frame that was partially decoded. (Note
 * that successfully drawing a partially decoded frame may not actually draw any
 * pixels!) Drawing again with FLAG_SYNC_DECODE would improve the result.
 *
 * WRONG_SIZE: We successfully drew a wrongly-sized frame that had to be scaled.
 * This is only returned if drawing again with FLAG_SYNC_DECODE would improve
 * the result; if the size requested was larger than the intrinsic size of the
 * image, for example, we would generally have to scale whether FLAG_SYNC_DECODE
 * was specified or not, and therefore we would not return WRONG_SIZE.
 *
 * NOT_READY: We failed to draw because no decoded version of the image was
 * available. Drawing again with FLAG_SYNC_DECODE would improve the result.
 * (Though FLAG_SYNC_DECODE will not necessarily work until after the image's
 * load event!)
 *
 * TEMPORARY_ERROR: We failed to draw due to a temporary error. Drawing may
 * succeed at a later time.
 *
 * BAD_IMAGE: We failed to draw because the image has an error. This is a
 * permanent condition.
 *
 * BAD_ARGS: We failed to draw because bad arguments were passed to draw().
 */
enum class MOZ_MUST_USE_TYPE ImgDrawResult : uint8_t
{
  SUCCESS,
  INCOMPLETE,
  WRONG_SIZE,
  NOT_READY,
  TEMPORARY_ERROR,
  BAD_IMAGE,
  BAD_ARGS
};

/**
 * You can combine ImgDrawResults with &. By analogy to bitwise-&, the result is
 * ImgDrawResult::SUCCESS only if both operands are ImgDrawResult::SUCCESS. Otherwise,
 * a failing ImgDrawResult is returned; we favor the left operand's failure when
 * deciding which failure to return, with the exception that we always prefer
 * any other kind of failure over ImgDrawResult::BAD_IMAGE, since other failures
 * are recoverable and we want to know if any recoverable failures occurred.
 */
inline ImgDrawResult
operator&(const ImgDrawResult aLeft, const ImgDrawResult aRight)
{
  if (MOZ_LIKELY(aLeft == ImgDrawResult::SUCCESS)) {
    return aRight;
  }
  if (aLeft == ImgDrawResult::BAD_IMAGE && aRight != ImgDrawResult::SUCCESS) {
    return aRight;
  }
  return aLeft;
}

inline ImgDrawResult&
operator&=(ImgDrawResult& aLeft, const ImgDrawResult aRight)
{
  aLeft = aLeft & aRight;
  return aLeft;
}

/**
 * A struct used during painting to provide input flags to determine how
 * imagelib draw calls should behave and an output ImgDrawResult to return
 * information about the result of any imagelib draw calls that may have
 * occurred.
 */
struct imgDrawingParams {
  explicit imgDrawingParams(uint32_t aImageFlags = 0)
    : imageFlags(aImageFlags), result(ImgDrawResult::SUCCESS)
  {}

  const uint32_t imageFlags; // imgIContainer::FLAG_* image flags to pass to
                             // image lib draw calls.
  ImgDrawResult result;         // To return results from image lib painting.
};

} // namespace image
} // namespace mozilla

#endif // mozilla_image_ImgDrawResult_h