/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include namespace android { namespace renderengine { namespace skia { // Mapping of resource substrings (1st element) that if found within a trace "dumpName" // should be mapped to the category name (2nd element). All char* used in a resourcePair // are expected to have a lifetime longer than the SkiaMemoryReporter in which they are used. typedef std::pair ResourcePair; /* * Utility class for logging the CPU/GPU usage of Skia caches in a format that is specific * to RenderEngine. HWUI has a similar logging class, but the data collected and the way * it is formatted and reported on are intended to be unique to each use case. */ class SkiaMemoryReporter : public SkTraceMemoryDump { public: /** * Creates the reporter class that can be populated by various Skia entry points, like * SkGraphics and GrContext, as well as format and log the results. * @param resourceMap An array of values that maps a Skia dumpName into a user defined category. * The first vector entry that matches the dumpName is used for the mapping. * @param itemize if true when logging the categories the individual elements will be printed * directly after the category details are printed. Otherwise, only the category * totals will be printed. */ SkiaMemoryReporter(const std::vector& resourceMap, bool itemize); ~SkiaMemoryReporter() override {} void logOutput(std::string& log, bool wrappedResources = false); void logTotals(std::string& log); void dumpNumericValue(const char* dumpName, const char* valueName, const char* units, uint64_t value) override; void dumpStringValue(const char* dumpName, const char* valueName, const char* value) override { // for convenience we just store this in the same format as numerical values dumpNumericValue(dumpName, valueName, value, 0); } void dumpWrappedState(const char* dumpName, bool isWrappedObject) override; LevelOfDetail getRequestedDetails() const override { return SkTraceMemoryDump::kLight_LevelOfDetail; } bool shouldDumpWrappedObjects() const override { return true; } void setMemoryBacking(const char*, const char*, const char*) override {} void setDiscardableMemoryBacking(const char*, const SkDiscardableMemory&) override {} private: struct TraceValue { TraceValue(const char* units, uint64_t value) : units(units), value(value), count(1) {} TraceValue(const TraceValue& v) : units(v.units), value(v.value), count(v.count) {} SkString units; float value; int count; }; const char* mapName(const char* resourceName); void processCurrentElement(); void resetCurrentElement(); TraceValue convertUnits(const TraceValue& value); const std::vector& mResourceMap; const bool mItemize; // variables storing the size of all non-wrapped elements being dumped TraceValue mTotalSize; TraceValue mPurgeableSize; // variables storing information on the current node being dumped std::string mCurrentElement; std::unordered_map mCurrentValues; bool mIsCurrentValueWrapped = false; // variable that stores the final format of the data after the individual elements are processed std::unordered_map> mResults; std::unordered_map> mWrappedResults; }; } /* namespace skia */ } /* namespace renderengine */ } /* namespace android */