spanification: Add SK_UNSAFE_TODO in gpu/graphite (1/7) As part of the effort to enforce -Wunsafe-buffer-usage across Skia, this patch inserts SK_UNSAFE_TODO macro in targeted lines that trigger the warning in a subset of files in the gpu/graphite directory, and deletes their file level check exclusion in unsafe_buffers_mappings. Upcoming follow-up work includes: - Refactoring existing code to use safe constructs (e.g., spans). - Expanding enforcement across directories beyond gpu/graphite. This CL introduces no behavior changes. Automated via: https://paste.googleplex.com/4903479387226112 Design doc: http://go/unsafe-buffer-skia Bug: b/565401613 Change-Id: I066e76247aa5fdfc4b204b6b0301542d17b92f21 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1375836 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Auto-Submit: Francisco Ochoa <frankchavez@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/include/private/SkLog.h b/include/private/SkLog.h index 8fb56f51..3f09b65 100644 --- a/include/private/SkLog.h +++ b/include/private/SkLog.h
@@ -32,7 +32,7 @@ #define SKIA_LOG(priority, fmt, ...) \ do { \ if constexpr (priority <= SKIA_LOWEST_ACTIVE_LOG_PRIORITY) { \ - SkLog(priority, "[skia] " fmt "\n", ##__VA_ARGS__); \ + SK_UNSAFE_TODO(SkLog)(priority, "[skia] " fmt "\n", ##__VA_ARGS__); \ } \ } while (0)
diff --git a/src/core/SkTraceEventCommon.h b/src/core/SkTraceEventCommon.h index 34c6011..c2ec41e 100644 --- a/src/core/SkTraceEventCommon.h +++ b/src/core/SkTraceEventCommon.h
@@ -5,6 +5,7 @@ #define SkTraceEventCommon_DEFINED #include "include/core/SkTypes.h" +#include "include/private/SkAttributes.h" #include "include/utils/SkTraceEventPhase.h" // Trace events are for tracking application performance and resource usage. @@ -216,7 +217,8 @@ template <typename... Args> static inline void sk_noop(Args...) {} #define TRACE_EMPTY(...) do { sk_noop(__VA_ARGS__); } while (0) -#define TRACE_EMPTY_FMT(fmt, ...) do { skprintf_like_noop(fmt, ##__VA_ARGS__); } while (0) +#define TRACE_EMPTY_FMT(fmt, ...) \ + do { SK_UNSAFE_TODO(skprintf_like_noop)(fmt, ##__VA_ARGS__); } while (0) #else #define TRACE_EMPTY(...) do {} while (0) #define TRACE_EMPTY_FMT(fmt, ...) do {} while (0) @@ -236,7 +238,7 @@ #define TRACE_EVENT_INSTANT0(cg, n, scope) TRACE_EMPTY(cg, n, scope) #define TRACE_EVENT_INSTANT1(cg, n, scope, a1n, a1v) TRACE_EMPTY(cg, n, scope, a1n, a1v) #define TRACE_EVENT_INSTANT2(cg, n, scope, a1n, a1v, a2n, a2v) \ - TRACE_EMPTY(cg, n, scope, a1n, a1v, a2n, a2v) + SK_UNSAFE_TODO(TRACE_EMPTY(cg, n, scope, a1n, a1v, a2n, a2v)) #define TRACE_EVENT_INSTANT0_ALWAYS(cg, n, scope) TRACE_EMPTY(cg, n, scope) #define TRACE_EVENT_INSTANT1_ALWAYS(cg, n, scope, a1n, a1v) TRACE_EMPTY(cg, n, scope, a1n, a1v) #define TRACE_EVENT_INSTANT2_ALWAYS(cg, n, scope, a1n, a1v, a2n, a2v) \ @@ -467,8 +469,9 @@ #define ATRACE_ANDROID_FRAMEWORK(fmt, ...) \ char SK_PERFETTO_UID(skTraceStrBuf)[SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE]; \ if (SkAndroidFrameworkTraceUtil::getEnableTracing()) { \ - snprintf(SK_PERFETTO_UID(skTraceStrBuf), SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE, \ - fmt, ##__VA_ARGS__); \ + SK_UNSAFE_TODO(snprintf)(SK_PERFETTO_UID(skTraceStrBuf), \ + SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE, \ + fmt, ##__VA_ARGS__); \ } \ TRACE_EVENT0("skia.android", TRACE_STR_COPY(SK_PERFETTO_UID(skTraceStrBuf))) @@ -528,8 +531,9 @@ #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \ arg2_name, arg2_val) \ - do { TRACE_EVENT_ATRACE_OR_PERFETTO(category_group, name, arg1_name, arg1_val, \ - arg2_name, arg2_val); } while(0) + do { SK_UNSAFE_TODO(TRACE_EVENT_ATRACE_OR_PERFETTO(category_group, name, \ + arg1_name, arg1_val, \ + arg2_name, arg2_val);) } while(0) // As above but appends the ".always" suffix #define TRACE_EVENT_INSTANT0_ALWAYS(category_group, name, scope) \ @@ -625,9 +629,9 @@ #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \ arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \ - TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val, \ - arg2_name, arg2_val) + SK_UNSAFE_TODO(INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \ + TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val, \ + arg2_name, arg2_val)) #define TRACE_EVENT_INSTANT0_ALWAYS(category_group, name, scope) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
diff --git a/src/gpu/graphite/BufferManager.cpp b/src/gpu/graphite/BufferManager.cpp index 44baa6a..3c31859 100644 --- a/src/gpu/graphite/BufferManager.cpp +++ b/src/gpu/graphite/BufferManager.cpp
@@ -10,6 +10,7 @@ #include "include/gpu/graphite/Recording.h" #include "include/private/SkAlign.h" #include "include/private/SkAssert.h" +#include "include/private/SkAttributes.h" #include "include/private/SkLog.h" #include "include/private/SkMath.h" #include "include/private/SkTo.h" @@ -534,7 +535,7 @@ if (alignedCount > count) { const uint32_t byteDiff = (alignedCount - count) * stride; void* zPtr = SkTAddOffset<void>(data, count * stride); - memset(zPtr, 0, byteDiff); + SK_UNSAFE_TODO(memset(zPtr, 0, byteDiff)); } return VertexWriter{data, size}; }
diff --git a/src/gpu/graphite/ClipAtlasManager.cpp b/src/gpu/graphite/ClipAtlasManager.cpp index ec06118..d77f52b 100644 --- a/src/gpu/graphite/ClipAtlasManager.cpp +++ b/src/gpu/graphite/ClipAtlasManager.cpp
@@ -14,6 +14,7 @@ #include "include/core/SkSize.h" #include "include/gpu/graphite/Recorder.h" #include "include/private/SkAssert.h" +#include "include/private/SkAttributes.h" #include "include/private/SkMalloc.h" #include "include/private/SkTArray.h" #include "src/core/SkAutoPixmapStorage.h" @@ -213,7 +214,7 @@ topLeft.y() + kEntryPadding + subsetRelativePos.y()); fDrawAtlas->setLastUseToken(entry->fLocator, recorder->priv().tokenTracker()->nextFlushToken()); - return fDrawAtlas->getProxies()[entry->fLocator.pageIndex()]; + return SK_UNSAFE_TODO(fDrawAtlas->getProxies()[entry->fLocator.pageIndex()]); } entry = entry->fNext; } @@ -300,7 +301,7 @@ fDrawAtlas->setLastUseToken(*locator, recorder->priv().tokenTracker()->nextFlushToken()); - return fDrawAtlas->getProxies()[locator->pageIndex()]; + return SK_UNSAFE_TODO(fDrawAtlas->getProxies()[locator->pageIndex()]); } bool ClipAtlasManager::DrawAtlasMgr::recordUploads(DrawContext* dc, Recorder* recorder) {
diff --git a/src/gpu/graphite/ClipStack.cpp b/src/gpu/graphite/ClipStack.cpp index bafd3dca..5e8d407 100644 --- a/src/gpu/graphite/ClipStack.cpp +++ b/src/gpu/graphite/ClipStack.cpp
@@ -19,6 +19,7 @@ #include "include/core/SkSpan.h" #include "include/core/SkStrokeRec.h" #include "include/gpu/graphite/Recorder.h" +#include "include/private/SkAttributes.h" #include "include/private/SkDebug.h" #include "include/private/SkEnumBitMask.h" #include "include/private/SkFloatingPoint.h" @@ -425,13 +426,14 @@ fLocalToDevice.inverseMapPoints(deviceQuad, localQuad, 4); for (int i = 0; i < 4; ++i) { // TODO: Would be nice to make this consistent with how the GPU clips NDC w. - if (deviceQuad[i].w < SkPathPriv::kW0PlaneDistance || - localQuad[i].w < SkPathPriv::kW0PlaneDistance) { + if (SK_UNSAFE_TODO(deviceQuad[i].w < SkPathPriv::kW0PlaneDistance) || + SK_UNSAFE_TODO(localQuad[i].w < SkPathPriv::kW0PlaneDistance)) { // Something in O actually projects behind the W = 0 plane and would be clipped // to infinity, so it's extremely unlikely that this contains O. return false; } - if (!fShape.conservativeContains(skvx::float2::Load(localQuad + i) / localQuad[i].w)) { + if (SK_UNSAFE_TODO(!fShape.conservativeContains(skvx::float2::Load(localQuad + i) / + localQuad[i].w))) { return false; } }
diff --git a/src/gpu/graphite/Context.cpp b/src/gpu/graphite/Context.cpp index c92d895..dfc5166 100644 --- a/src/gpu/graphite/Context.cpp +++ b/src/gpu/graphite/Context.cpp
@@ -34,6 +34,7 @@ #include "include/gpu/graphite/Surface.h" #include "include/private/SingleOwner.h" #include "include/private/SkAlign.h" +#include "include/private/SkAttributes.h" #include "include/private/SkEnumBitMask.h" #include "include/private/SkLog.h" #include "include/private/SkMutex.h" @@ -708,7 +709,7 @@ // This matrix generates (r,g,b,a) = (0, 0, 0, y) float yM[20]; std::fill_n(yM, 15, 0.f); - std::copy_n(baseM + 0, 5, yM + 15); + SK_UNSAFE_TODO(std::copy_n(baseM + 0, 5, yM + 15)); if (!copyPlane(yaInfo, "AsyncReadPixelsYPlane", yM, texMatrix, &transfers[0])) { return params.fail(); } @@ -730,7 +731,7 @@ // This matrix generates (r,g,b,a) = (0, 0, 0, u) float uM[20]; std::fill_n(uM, 15, 0.f); - std::copy_n(baseM + 5, 5, uM + 15); + SK_UNSAFE_TODO(std::copy_n(baseM + 5, 5, uM + 15)); if (!copyPlane(uvInfo, "AsyncReadPixelsUPlane", uM, texMatrix, &transfers[1])) { return params.fail(); } @@ -738,7 +739,7 @@ // This matrix generates (r,g,b,a) = (0, 0, 0, v) float vM[20]; std::fill_n(vM, 15, 0.f); - std::copy_n(baseM + 10, 5, vM + 15); + SK_UNSAFE_TODO(std::copy_n(baseM + 10, 5, vM + 15)); if (!copyPlane(uvInfo, "AsyncReadPixelsVPlane", vM, texMatrix, &transfers[2])) { return params.fail(); } @@ -911,9 +912,10 @@ const void* src) { if (flipY) { for (int y = 0; y < dstInfo.height(); ++y) { - const auto* srcRow = static_cast<const char*>(src) + - (dstInfo.height() - 1 - y) * rowBytes; - auto* dstRow = static_cast<char*>(dst) + y * dstInfo.minRowBytes(); + const auto* srcRow = SK_UNSAFE_TODO(static_cast<const char*>(src) + + (dstInfo.height() - 1 - y) * rowBytes); + auto* dstRow = + SK_UNSAFE_TODO(static_cast<char*>(dst) + y * dstInfo.minRowBytes()); cpuXferFn.run(dstInfo.width(), 1, srcRow, rowBytes, dstRow, dstInfo.minRowBytes());
diff --git a/src/gpu/graphite/Device.cpp b/src/gpu/graphite/Device.cpp index 0ac816e..d981a78 100644 --- a/src/gpu/graphite/Device.cpp +++ b/src/gpu/graphite/Device.cpp
@@ -40,6 +40,7 @@ #include "include/gpu/graphite/TextureInfo.h" #include "include/private/SingleOwner.h" #include "include/private/SkAssert.h" +#include "include/private/SkAttributes.h" #include "include/private/SkFloatingPoint.h" #include "include/private/SkTo.h" #include "src/core/SkArenaAlloc.h" @@ -1295,7 +1296,7 @@ break; } - strokeCorners[i] = {strokeCorner, strokeCorner}; + SK_UNSAFE_TODO(strokeCorners[i]) = {strokeCorner, strokeCorner}; validCorners++; } @@ -1442,19 +1443,20 @@ // SkPaint paintWithShader(paint); int dstClipIndex = 0; for (int i = 0; i < count; ++i) { + const auto& entry = SK_UNSAFE_TODO(set[i]); // If the entry is clipped by 'dstClips', that must be provided - SkASSERT(!set[i].fHasClip || dstClips); + SkASSERT(!entry.fHasClip || dstClips); // Similarly, if it has an extra transform, those must be provided - SkASSERT(set[i].fMatrixIndex < 0 || preViewMatrices); + SkASSERT(entry.fMatrixIndex < 0 || preViewMatrices); // See SkImageShader::MakeForDrawRect, as this behavior is consistent but avoids // allocating SkShader objects or having to modify the SkPaint. // Adjust `dst` such that it only samples from the portion of fSrcRect that overlaps with // the image bounds. This "decal" effect is applied geometrically to what is drawn so that // actual texture tiling can be clamped to the src rect. - const SkRect imageBounds = SkRect::Make(set[i].fImage->bounds()); - SkRect dstToDraw = set[i].fDstRect; - SkRect subset = set[i].fSrcRect; + const SkRect imageBounds = SkRect::Make(entry.fImage->bounds()); + SkRect dstToDraw = entry.fDstRect; + SkRect subset = entry.fSrcRect; SkMatrix localMatrix = SkMatrix::RectToRectOrIdentity(subset, dstToDraw); if (!imageBounds.contains(subset)) { if (subset.intersect(imageBounds)) { @@ -1466,16 +1468,16 @@ } if (!dstToDraw.isEmpty()) { PaintParams::SimpleImage imageShader{ - set[i].fImage.get(), + entry.fImage.get(), &localMatrix, constraint == SkCanvas::kStrict_SrcRectConstraint ? subset : imageBounds, sampling}; // NOTE: See drawEdgeAAQuad for details, we do not snap non-AA quads. - SkEnumBitMask<EdgeAAQuad::Flags> flags = - static_cast<EdgeAAQuad::Flags>(set[i].fAAFlags); - EdgeAAQuad quad = set[i].fHasClip ? EdgeAAQuad(dstClips + dstClipIndex, flags) - : EdgeAAQuad(dstToDraw, flags); + SkEnumBitMask<EdgeAAQuad::Flags> flags = static_cast<EdgeAAQuad::Flags>(entry.fAAFlags); + EdgeAAQuad quad = entry.fHasClip + ? EdgeAAQuad(SK_UNSAFE_TODO(dstClips + dstClipIndex), flags) + : EdgeAAQuad(dstToDraw, flags); // TODO: Calling drawGeometry() for each entry re-evaluates the clip stack every time, // which is consistent with Ganesh's behavior. It also matches the behavior if edge-AA @@ -1483,13 +1485,14 @@ // However, we should explore the performance trade off with doing one bulk evaluation // for the whole set const SkMatrix* xtraXform = - set[i].fMatrixIndex < 0 ? nullptr : &preViewMatrices[set[i].fMatrixIndex]; + entry.fMatrixIndex < 0 ? nullptr + : SK_UNSAFE_TODO(&preViewMatrices[entry.fMatrixIndex]); this->drawGeometry(xtraXform ? localToDevice.concat(SkM44(*xtraXform)) : localToDevice, Geometry(quad), - PaintParams(paint, imageShader, set[i].fAlpha), + PaintParams(paint, imageShader, entry.fAlpha), DefaultFillStyle()); } - dstClipIndex += 4 * set[i].fHasClip; + dstClipIndex += 4 * entry.fHasClip; } }
diff --git a/src/gpu/graphite/DrawAtlas.h b/src/gpu/graphite/DrawAtlas.h index 8238a2a..dccf244 100644 --- a/src/gpu/graphite/DrawAtlas.h +++ b/src/gpu/graphite/DrawAtlas.h
@@ -13,6 +13,7 @@ #include "include/core/SkRefCnt.h" #include "include/core/SkSize.h" #include "include/private/SkAssert.h" +#include "include/private/SkAttributes.h" #include "include/private/SkDebug.h" #include "include/private/SkTArray.h" #include "src/core/SkIPoint16.h" @@ -155,8 +156,8 @@ }; // DEPRECATED - class PlotLocator; class AtlasLocator; + class PlotLocator; /** * An interface for eviction callbacks. Whenever an atlas evicts a specific PlotLocator, @@ -295,12 +296,12 @@ void updatePlot(Plot* plot, AtlasLocator*); void makeMRU(Plot* plot, int pageIdx) { - if (fPages[pageIdx].fPlotList.head() == plot) { + if (SK_UNSAFE_TODO(fPages[pageIdx].fPlotList.head()) == plot) { return; } - fPages[pageIdx].fPlotList.remove(plot); - fPages[pageIdx].fPlotList.addToHead(plot); + SK_UNSAFE_TODO(fPages[pageIdx].fPlotList.remove(plot)); + SK_UNSAFE_TODO(fPages[pageIdx].fPlotList.addToHead(plot)); // No MRU update for pages -- since we will always try to add from // the front and remove from the back there is no need for MRU. @@ -319,7 +320,8 @@ int count = 0; PlotList::Iter plotIter; for (uint32_t pageIndex = 0; pageIndex < this->maxPages(); ++pageIndex) { - plotIter.init(fPages[pageIndex].fPlotList, PlotList::Iter::kHead_IterStart); + plotIter.init(SK_UNSAFE_TODO(fPages[pageIndex].fPlotList), + PlotList::Iter::kHead_IterStart); while (Plot* plot = plotIter.get()) { if (func(plot)) { count++; @@ -488,9 +490,12 @@ */ class DrawAtlas::BulkUsePlotUpdater { public: - BulkUsePlotUpdater() { memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated)); } + BulkUsePlotUpdater() { + SK_UNSAFE_TODO(memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated))); + } BulkUsePlotUpdater(const BulkUsePlotUpdater& that) : fPlotsToUpdate(that.fPlotsToUpdate) { - memcpy(fPlotAlreadyUpdated, that.fPlotAlreadyUpdated, sizeof(fPlotAlreadyUpdated)); + SK_UNSAFE_TODO( + memcpy(fPlotAlreadyUpdated, that.fPlotAlreadyUpdated, sizeof(fPlotAlreadyUpdated))); } bool add(const AtlasLocator& atlasLocator) { @@ -505,7 +510,7 @@ void reset() { fPlotsToUpdate.clear(); - memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated)); + SK_UNSAFE_TODO(memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated))); } struct PlotData { @@ -521,12 +526,12 @@ private: bool find(int pageIdx, int index) const { SkASSERT(index < kMaxPlots); - return (fPlotAlreadyUpdated[pageIdx] >> index) & 1; + return (SK_UNSAFE_TODO(fPlotAlreadyUpdated[pageIdx]) >> index) & 1; } void set(int pageIdx, int index) { SkASSERT(!this->find(pageIdx, index)); - fPlotAlreadyUpdated[pageIdx] |= (1 << index); + SK_UNSAFE_TODO(fPlotAlreadyUpdated[pageIdx] |= (1 << index)); fPlotsToUpdate.push_back(PlotData(pageIdx, index)); } @@ -720,7 +725,7 @@ uint32_t plot = plotLocator.plotIndex(); uint32_t page = plotLocator.pageIndex(); - uint64_t plotGeneration = fPages[page].fPlotArray[plot]->genID(); + uint64_t plotGeneration = SK_UNSAFE_TODO(fPages[page].fPlotArray[plot]->genID()); uint64_t locatorGeneration = plotLocator.genID(); return plot < fNumPlots && page < fNumActivePages && plotGeneration == locatorGeneration; } @@ -737,7 +742,7 @@ // it's possible we've added a plot to the updater and subsequently the plot's page // was deleted -- so we check to prevent a crash if (pd.fPageIndex < fNumActivePages) { - Plot* plot = fPages[pd.fPageIndex].fPlotArray[pd.fPlotIndex].get(); + Plot* plot = SK_UNSAFE_TODO(fPages[pd.fPageIndex].fPlotArray[pd.fPlotIndex].get()); this->internalSetLastUseToken(plot, pd.fPageIndex, token); } } @@ -747,7 +752,7 @@ SkASSERT(this->hasID(atlasLocator.plotLocator())); uint32_t pageIdx = atlasLocator.pageIndex(); uint32_t plotIdx = atlasLocator.plotIndex(); - return fPages[pageIdx].fPlotArray[plotIdx].get(); + return SK_UNSAFE_TODO(fPages[pageIdx].fPlotArray[plotIdx].get()); } inline void DrawAtlas::internalSetLastUseToken(Plot* plot, uint32_t pageIdx, Token token) {
diff --git a/src/gpu/graphite/DrawListBase.h b/src/gpu/graphite/DrawListBase.h index 69c765a..814859e 100644 --- a/src/gpu/graphite/DrawListBase.h +++ b/src/gpu/graphite/DrawListBase.h
@@ -9,6 +9,7 @@ #include "include/gpu/graphite/GraphiteTypes.h" +#include "include/private/SkAttributes.h" #include "include/private/SkDebug.h" #include "include/private/SkEnumBitMask.h" #include "src/core/SkBlockAllocator.h" @@ -31,11 +32,11 @@ namespace skgpu::graphite { -class DrawPass; class DrawContext; +class DrawPass; class Geometry; -class Renderer; class Recorder; +class Renderer; struct Layer; @@ -272,8 +273,8 @@ for (int i = 0; i < binding.numTextures(); ++i) { auto [t, s] = binding.texture(i); - textures[i] = t.get(); - samplers[i] = s; + SK_UNSAFE_TODO(textures[i]) = t.get(); + SK_UNSAFE_TODO(samplers[i]) = s; } }
diff --git a/tools/unsafe_buffers/unsafe_buffers_mappings.txt b/tools/unsafe_buffers/unsafe_buffers_mappings.txt index 983dd99..ee4f6e4 100644 --- a/tools/unsafe_buffers/unsafe_buffers_mappings.txt +++ b/tools/unsafe_buffers/unsafe_buffers_mappings.txt
@@ -23,17 +23,7 @@ # Temporary exclusions. # TODO(564587252): Convert files to SK_UNSAFE_TODO instead of # file-wide suppressions. -src:*src/gpu/graphite/BufferManager.cpp -src:*src/gpu/graphite/ClipAtlasManager.cpp -src:*src/gpu/graphite/ClipStack.cpp -src:*src/gpu/graphite/Context.cpp -src:*src/gpu/graphite/Device.cpp src:*src/gpu/graphite/DrawAtlas.cpp -src:*src/gpu/graphite/DrawAtlas.h -src:*src/gpu/graphite/DrawContext.cpp -src:*src/gpu/graphite/DrawListBase.h -src:*src/gpu/graphite/DrawPass.cpp -src:*src/gpu/graphite/GlobalCache.cpp src:*src/gpu/graphite/GraphicsPipeline.cpp src:*src/gpu/graphite/ImageFactories.cpp src:*src/gpu/graphite/Image_YUVA_Graphite.cpp