ProfilerScreenshots.h (4493B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_ProfilerScreenshots_h 8 #define mozilla_layers_ProfilerScreenshots_h 9 10 #include <functional> 11 12 #include "mozilla/Mutex.h" 13 #include "mozilla/RefPtr.h" 14 #include "mozilla/TimeStamp.h" 15 #include "nsCOMPtr.h" 16 #include "nsTArray.h" 17 18 #include "mozilla/gfx/Point.h" 19 20 class nsIThread; 21 22 namespace mozilla { 23 24 namespace gfx { 25 class DataSourceSurface; 26 } 27 28 namespace layers { 29 30 /** 31 * Can be used to submit screenshots from the compositor to the profiler. 32 * Screenshots have a fixed bounding size. The user of this class will usually 33 * scale down the window contents first, ideally on the GPU, then read back the 34 * small scaled down image into main memory, and then call SubmitScreenshot to 35 * pass the data to the profiler. 36 * This class encodes each screenshot to a JPEG data URL, on a separate thread. 37 * This class manages that thread and recycles memory buffers. 38 * Users of ProfilerScreenshots should have one ProfilerScreenshot instance per 39 * window, as a unique window id is created by the constructor. 40 */ 41 class ProfilerScreenshots final { 42 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProfilerScreenshots) 43 44 public: 45 ProfilerScreenshots(); 46 47 /** 48 * Returns whether the profiler is currently active and is running with the 49 * "screenshots" feature enabled. 50 */ 51 static bool IsEnabled(); 52 53 /** 54 * Returns a fixed size that all screenshots should be resized to fit into. 55 */ 56 static gfx::IntSize ScreenshotSize() { return gfx::IntSize(350, 350); } 57 58 /** 59 * The main functionality provided by this class. 60 * This method will synchronously invoke the supplied aPopulateSurface 61 * callback function with a DataSourceSurface in which the callback should 62 * store the pixel data. This surface may be larger than aScaledSize, but 63 * only the data in the rectangle (0, 0, aScaledSize.width, 64 * aScaledSize.height) will be read. 65 * @param aWindowIdentifier A pointer-sized integer that can be used to match 66 * up multiple screenshots from the same window. 67 * @param aOriginalSize The unscaled size of the snapshotted window. 68 * @param aScaledSize The scaled size, aScaled <= ScreenshotSize(), which the 69 * snapshot has been resized to. 70 * @param aTimeStamp The time at which the snapshot was taken. In 71 * asynchronous readback implementations, this is the time at which the 72 * readback / copy command was put into the command stream to the GPU, not 73 * the time at which the readback data was mapped into main memory. 74 * @param aPopulateSurface A callback that the caller needs to implement, 75 * which needs to copy the screenshot pixel data into the surface that's 76 * supplied to the callback. Called zero or one times, synchronously. 77 */ 78 void SubmitScreenshot( 79 const gfx::IntSize& aOriginalSize, const gfx::IntSize& aScaledSize, 80 const TimeStamp& aTimeStamp, 81 const std::function<bool(gfx::DataSourceSurface*)>& aPopulateSurface); 82 83 private: 84 ~ProfilerScreenshots(); 85 86 /** 87 * Recycle a surface from mAvailableSurfaces or create a new one if all 88 * surfaces are currently in use, up to some maximum limit. 89 * Returns null if the limit is reached. 90 * Can be called on any thread. 91 */ 92 already_AddRefed<gfx::DataSourceSurface> TakeNextSurface(); 93 94 /** 95 * Return aSurface back into the mAvailableSurfaces pool. Can be called on 96 * any thread. 97 */ 98 void ReturnSurface(gfx::DataSourceSurface* aSurface); 99 100 // An array of surfaces ready to be recycled. Can be accessed from multiple 101 // threads, protected by mMutex. 102 nsTArray<RefPtr<gfx::DataSourceSurface>> mAvailableSurfaces; 103 // Protects mAvailableSurfaces. 104 Mutex mMutex MOZ_UNANNOTATED; 105 // The total number of surfaces created. If encoding is fast enough to happen 106 // entirely in the time between two calls to SubmitScreenshot, this should 107 // never exceed 1. 108 uint32_t mLiveSurfaceCount; 109 110 // Window identifier used to submit screenshots, created in the constructor. 111 uint32_t mWindowIdentifier; 112 113 // Counter incremented each time a new instance is constructed. 114 static uint32_t sWindowCounter; 115 }; 116 117 } // namespace layers 118 } // namespace mozilla 119 120 #endif // mozilla_layers_ProfilerScreenshots_h