summaryrefslogtreecommitdiffstats
path: root/image/LookupResult.h
blob: bbd1cca2a7f28f3cd117dd59a2c0ebbde9d47393 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* -*- 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/. */

/**
 * LookupResult is the return type of SurfaceCache's Lookup*() functions. It
 * combines a surface with relevant metadata tracked by SurfaceCache.
 */

#ifndef mozilla_image_LookupResult_h
#define mozilla_image_LookupResult_h

#include <utility>

#include "ISurfaceProvider.h"
#include "mozilla/Attributes.h"
#include "mozilla/gfx/Point.h"  // for IntSize

namespace mozilla {
namespace image {

enum class MatchType : uint8_t {
  NOT_FOUND,  // No matching surface and no placeholder.
  PENDING,    // Found a matching placeholder, but no surface.
  EXACT,      // Found a surface that matches exactly.
  SUBSTITUTE_BECAUSE_NOT_FOUND,  // No exact match, but found a similar one.
  SUBSTITUTE_BECAUSE_PENDING,    // Found a similar surface and a placeholder
                                 // for an exact match.

  /* No exact match, but this should be considered an exact match for purposes
   * of deciding whether or not to request a new decode. This is because the
   * cache has determined that callers require too many size variants of this
   * image. It determines the set of sizes which best represent the image, and
   * will only suggest decoding of unavailable sizes from that set. */
  SUBSTITUTE_BECAUSE_BEST
};

/**
 * LookupResult is the return type of SurfaceCache's Lookup*() functions. It
 * combines a surface with relevant metadata tracked by SurfaceCache.
 */
class MOZ_STACK_CLASS LookupResult {
 public:
  explicit LookupResult(MatchType aMatchType)
      : mMatchType(aMatchType), mFailedToRequestDecode(false) {
    MOZ_ASSERT(
        mMatchType == MatchType::NOT_FOUND || mMatchType == MatchType::PENDING,
        "Only NOT_FOUND or PENDING make sense with no surface");
  }

  LookupResult(LookupResult&& aOther)
      : mSurface(std::move(aOther.mSurface)),
        mMatchType(aOther.mMatchType),
        mSuggestedSize(aOther.mSuggestedSize),
        mFailedToRequestDecode(aOther.mFailedToRequestDecode) {}

  LookupResult(DrawableSurface&& aSurface, MatchType aMatchType)
      : mSurface(std::move(aSurface)),
        mMatchType(aMatchType),
        mFailedToRequestDecode(false) {
    MOZ_ASSERT(!mSurface || !(mMatchType == MatchType::NOT_FOUND ||
                              mMatchType == MatchType::PENDING),
               "Only NOT_FOUND or PENDING make sense with no surface");
    MOZ_ASSERT(mSurface || mMatchType == MatchType::NOT_FOUND ||
                   mMatchType == MatchType::PENDING,
               "NOT_FOUND or PENDING do not make sense with a surface");
  }

  LookupResult(MatchType aMatchType, const gfx::IntSize& aSuggestedSize)
      : mMatchType(aMatchType),
        mSuggestedSize(aSuggestedSize),
        mFailedToRequestDecode(false) {
    MOZ_ASSERT(
        mMatchType == MatchType::NOT_FOUND || mMatchType == MatchType::PENDING,
        "Only NOT_FOUND or PENDING make sense with no surface");
  }

  LookupResult(DrawableSurface&& aSurface, MatchType aMatchType,
               const gfx::IntSize& aSuggestedSize)
      : mSurface(std::move(aSurface)),
        mMatchType(aMatchType),
        mSuggestedSize(aSuggestedSize),
        mFailedToRequestDecode(false) {
    MOZ_ASSERT(!mSurface || !(mMatchType == MatchType::NOT_FOUND ||
                              mMatchType == MatchType::PENDING),
               "Only NOT_FOUND or PENDING make sense with no surface");
    MOZ_ASSERT(mSurface || mMatchType == MatchType::NOT_FOUND ||
                   mMatchType == MatchType::PENDING,
               "NOT_FOUND or PENDING do not make sense with a surface");
  }

  LookupResult& operator=(LookupResult&& aOther) {
    MOZ_ASSERT(&aOther != this, "Self-move-assignment is not supported");
    mSurface = std::move(aOther.mSurface);
    mMatchType = aOther.mMatchType;
    mSuggestedSize = aOther.mSuggestedSize;
    mFailedToRequestDecode = aOther.mFailedToRequestDecode;
    return *this;
  }

  DrawableSurface& Surface() { return mSurface; }
  const DrawableSurface& Surface() const { return mSurface; }
  const gfx::IntSize& SuggestedSize() const { return mSuggestedSize; }

  /// @return true if this LookupResult contains a surface.
  explicit operator bool() const { return bool(mSurface); }

  /// @return what kind of match this is (exact, substitute, etc.)
  MatchType Type() const { return mMatchType; }

  void SetFailedToRequestDecode() { mFailedToRequestDecode = true; }
  bool GetFailedToRequestDecode() { return mFailedToRequestDecode; }

 private:
  LookupResult(const LookupResult&) = delete;
  LookupResult& operator=(const LookupResult& aOther) = delete;

  DrawableSurface mSurface;
  MatchType mMatchType;

  /// mSuggestedSize will be the size of the returned surface if the result is
  /// SUBSTITUTE_BECAUSE_BEST. It will be empty for EXACT, and can contain a
  /// non-empty size possibly different from the returned surface (if any) for
  /// all other results. If non-empty, it will always be the size the caller
  /// should request any decodes at.
  gfx::IntSize mSuggestedSize;

  // True if we tried to start a decode but failed, likely because the image was
  // too big to fit into the surface cache.
  bool mFailedToRequestDecode;
};

}  // namespace image
}  // namespace mozilla

#endif  // mozilla_image_LookupResult_h