Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/gpu/SkGpuDevice.cpp

Issue 1205643002: Make SkGpuDevice know its alpha type (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix bench pictures :( Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/SkGpuDevice.h ('k') | src/image/SkImage_Gpu.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkGpuDevice.h" 8 #include "SkGpuDevice.h"
9 9
10 #include "GrBlurUtils.h" 10 #include "GrBlurUtils.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 115
116 struct GrSkDrawProcs : public SkDrawProcs { 116 struct GrSkDrawProcs : public SkDrawProcs {
117 public: 117 public:
118 GrContext* fContext; 118 GrContext* fContext;
119 GrTextContext* fTextContext; 119 GrTextContext* fTextContext;
120 GrFontScaler* fFontScaler; // cached in the skia glyphcache 120 GrFontScaler* fFontScaler; // cached in the skia glyphcache
121 }; 121 };
122 122
123 /////////////////////////////////////////////////////////////////////////////// 123 ///////////////////////////////////////////////////////////////////////////////
124 124
125 SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props , unsigned flags) { 125 /** Checks that the alpha type is legal and gets constructor flags. Returns fals e if device creation
126 return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, flags); 126 should fail. */
127 bool SkGpuDevice::CheckAlphaTypeAndGetFlags(
128 const SkImageInfo* info, SkGpuDevice::InitContents init, unsigned* flags) {
129 *flags = 0;
130 if (info) {
131 switch (info->alphaType()) {
132 case kPremul_SkAlphaType:
133 break;
134 case kOpaque_SkAlphaType:
135 *flags |= SkGpuDevice::kIsOpaque_Flag;
136 break;
137 default: // If it is unpremul or unknown don't try to render
138 return false;
139 }
140 }
141 if (kClear_InitContents == init) {
142 *flags |= kNeedClear_Flag;
143 }
144 return true;
145 }
146
147 SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props ,
148 InitContents init) {
149 return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, init);
127 } 150 }
128 151
129 SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, int width, int height, 152 SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, int width, int height,
130 const SkSurfaceProps* props, unsigned flags) { 153 const SkSurfaceProps* props, InitContents init) {
131 if (!rt || rt->wasDestroyed()) { 154 if (!rt || rt->wasDestroyed()) {
132 return NULL; 155 return NULL;
133 } 156 }
157 unsigned flags;
158 if (!CheckAlphaTypeAndGetFlags(NULL, init, &flags)) {
159 return NULL;
160 }
134 return SkNEW_ARGS(SkGpuDevice, (rt, width, height, props, flags)); 161 return SkNEW_ARGS(SkGpuDevice, (rt, width, height, props, flags));
135 } 162 }
136 163
164 SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgete d,
165 const SkImageInfo& info, int sampleCount,
166 const SkSurfaceProps* props, InitContents init) {
167 unsigned flags;
168 if (!CheckAlphaTypeAndGetFlags(&info, init, &flags)) {
169 return NULL;
170 }
171
172 SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount));
173 if (NULL == rt) {
174 return NULL;
175 }
176
177 return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flag s));
178 }
179
137 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height, 180 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height,
138 const SkSurfaceProps* props, unsigned flags) 181 const SkSurfaceProps* props, unsigned flags)
139 : INHERITED(SkSurfacePropsCopyOrDefault(props)) 182 : INHERITED(SkSurfacePropsCopyOrDefault(props))
140 { 183 {
141 fDrawProcs = NULL; 184 fDrawProcs = NULL;
142 185
143 fContext = SkRef(rt->getContext()); 186 fContext = SkRef(rt->getContext());
144 fNeedClear = flags & kNeedClear_Flag; 187 fNeedClear = SkToBool(flags & kNeedClear_Flag);
188 fOpaque = SkToBool(flags & kIsOpaque_Flag);
145 189
146 fRenderTarget = SkRef(rt); 190 fRenderTarget = SkRef(rt);
147 191
148 SkImageInfo info = rt->surfacePriv().info().makeWH(width, height); 192 SkAlphaType at = fOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
193 SkImageInfo info = rt->surfacePriv().info(at).makeWH(width, height);
149 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); 194 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
150 fLegacyBitmap.setInfo(info); 195 fLegacyBitmap.setInfo(info);
151 fLegacyBitmap.setPixelRef(pr)->unref(); 196 fLegacyBitmap.setPixelRef(pr)->unref();
152 197
153 fDrawContext.reset(SkRef(fContext->drawContext(&this->surfaceProps()))); 198 fDrawContext.reset(SkRef(fContext->drawContext(&this->surfaceProps())));
154 } 199 }
155 200
156 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B udgeted budgeted, 201 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B udgeted budgeted,
157 const SkImageInfo& origInfo, int sampleCount) { 202 const SkImageInfo& origInfo, int sampleCount) {
158 if (kUnknown_SkColorType == origInfo.colorType() || 203 if (kUnknown_SkColorType == origInfo.colorType() ||
(...skipping 26 matching lines...) Expand all
185 desc.fSampleCnt = sampleCount; 230 desc.fSampleCnt = sampleCount;
186 GrTexture* texture = context->textureProvider()->createTexture( 231 GrTexture* texture = context->textureProvider()->createTexture(
187 desc, SkToBool(budgeted), NULL, 0); 232 desc, SkToBool(budgeted), NULL, 0);
188 if (NULL == texture) { 233 if (NULL == texture) {
189 return NULL; 234 return NULL;
190 } 235 }
191 SkASSERT(NULL != texture->asRenderTarget()); 236 SkASSERT(NULL != texture->asRenderTarget());
192 return texture->asRenderTarget(); 237 return texture->asRenderTarget();
193 } 238 }
194 239
195 SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgete d,
196 const SkImageInfo& info, int sampleCount,
197 const SkSurfaceProps* props, unsigned flags) {
198
199 SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount));
200 if (NULL == rt) {
201 return NULL;
202 }
203
204 return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flag s));
205 }
206
207 SkGpuDevice::~SkGpuDevice() { 240 SkGpuDevice::~SkGpuDevice() {
208 if (fDrawProcs) { 241 if (fDrawProcs) {
209 delete fDrawProcs; 242 delete fDrawProcs;
210 } 243 }
211 244
212 fRenderTarget->unref(); 245 fRenderTarget->unref();
213 fContext->unref(); 246 fContext->unref();
214 } 247 }
215 248
216 /////////////////////////////////////////////////////////////////////////////// 249 ///////////////////////////////////////////////////////////////////////////////
217 250
218 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size _t dstRowBytes, 251 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size _t dstRowBytes,
219 int x, int y) { 252 int x, int y) {
220 DO_DEFERRED_CLEAR(); 253 DO_DEFERRED_CLEAR();
221 254
222 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p ixels 255 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p ixels
223 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo); 256 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo);
224 if (kUnknown_GrPixelConfig == config) { 257 if (kUnknown_GrPixelConfig == config) {
225 return false; 258 return false;
226 } 259 }
227 260
228 uint32_t flags = 0; 261 uint32_t flags = 0;
229 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { 262 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
230 flags = GrContext::kUnpremul_PixelOpsFlag; 263 flags = GrContext::kUnpremul_PixelOpsFlag;
231 } 264 }
232 return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width() , dstInfo.height(), 265 return fRenderTarget->readPixels(x, y, dstInfo.width(), dstInfo.height(), co nfig, dstPixels,
233 config, dstPixels, dstRowBytes, flag s); 266 dstRowBytes, flags);
234 } 267 }
235 268
236 bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, siz e_t rowBytes, 269 bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, siz e_t rowBytes,
237 int x, int y) { 270 int x, int y) {
238 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p ixels 271 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p ixels
239 GrPixelConfig config = SkImageInfo2GrPixelConfig(info); 272 GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
240 if (kUnknown_GrPixelConfig == config) { 273 if (kUnknown_GrPixelConfig == config) {
241 return false; 274 return false;
242 } 275 }
243 uint32_t flags = 0; 276 uint32_t flags = 0;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 return; 357 return;
325 } 358 }
326 this->context()->copySurface(newRT, fRenderTarget); 359 this->context()->copySurface(newRT, fRenderTarget);
327 } 360 }
328 361
329 SkASSERT(fRenderTarget != newRT); 362 SkASSERT(fRenderTarget != newRT);
330 363
331 fRenderTarget->unref(); 364 fRenderTarget->unref();
332 fRenderTarget = newRT.detach(); 365 fRenderTarget = newRT.detach();
333 366
334 SkASSERT(fRenderTarget->surfacePriv().info() == fLegacyBitmap.info()); 367 #ifdef SK_DEBUG
335 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fRenderTarget->surfacePriv().info (), fRenderTarget)); 368 SkImageInfo info = fRenderTarget->surfacePriv().info(fOpaque ? kOpaque_SkAlp haType :
369 kPremul_SkAlp haType);
370 SkASSERT(info == fLegacyBitmap.info());
371 #endif
372 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fLegacyBitmap.info(), fRenderTarg et));
336 fLegacyBitmap.setPixelRef(pr)->unref(); 373 fLegacyBitmap.setPixelRef(pr)->unref();
337 374
338 fDrawContext.reset(SkRef(fRenderTarget->getContext()->drawContext(&this->sur faceProps()))); 375 fDrawContext.reset(SkRef(fRenderTarget->getContext()->drawContext(&this->sur faceProps())));
339 } 376 }
340 377
341 /////////////////////////////////////////////////////////////////////////////// 378 ///////////////////////////////////////////////////////////////////////////////
342 379
343 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { 380 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
344 CHECK_SHOULD_DRAW(draw); 381 CHECK_SHOULD_DRAW(draw);
345 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext); 382 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext);
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 692
656 if (maxTileTotalTileSize > 2 * smallTotalTileSize) { 693 if (maxTileTotalTileSize > 2 * smallTotalTileSize) {
657 return kBmpSmallTileSize; 694 return kBmpSmallTileSize;
658 } else { 695 } else {
659 return maxTileSize; 696 return maxTileSize;
660 } 697 }
661 } 698 }
662 699
663 // Given a bitmap, an optional src rect, and a context with a clip and matrix de termine what 700 // Given a bitmap, an optional src rect, and a context with a clip and matrix de termine what
664 // pixels from the bitmap are necessary. 701 // pixels from the bitmap are necessary.
665 static void determine_clipped_src_rect(const GrContext* context, 702 static void determine_clipped_src_rect(const GrRenderTarget* rt,
666 const GrRenderTarget* rt,
667 const GrClip& clip, 703 const GrClip& clip,
668 const SkMatrix& viewMatrix, 704 const SkMatrix& viewMatrix,
669 const SkBitmap& bitmap, 705 const SkBitmap& bitmap,
670 const SkRect* srcRectPtr, 706 const SkRect* srcRectPtr,
671 SkIRect* clippedSrcIRect) { 707 SkIRect* clippedSrcIRect) {
672 clip.getConservativeBounds(rt, clippedSrcIRect, NULL); 708 clip.getConservativeBounds(rt, clippedSrcIRect, NULL);
673 SkMatrix inv; 709 SkMatrix inv;
674 if (!viewMatrix.invert(&inv)) { 710 if (!viewMatrix.invert(&inv)) {
675 clippedSrcIRect->setEmpty(); 711 clippedSrcIRect->setEmpty();
676 return; 712 return;
(...skipping 22 matching lines...) Expand all
699 int maxTileSize, 735 int maxTileSize,
700 int* tileSize, 736 int* tileSize,
701 SkIRect* clippedSrcRect) const { 737 SkIRect* clippedSrcRect) const {
702 // if bitmap is explictly texture backed then just use the texture 738 // if bitmap is explictly texture backed then just use the texture
703 if (bitmap.getTexture()) { 739 if (bitmap.getTexture()) {
704 return false; 740 return false;
705 } 741 }
706 742
707 // if it's larger than the max tile size, then we have no choice but tiling. 743 // if it's larger than the max tile size, then we have no choice but tiling.
708 if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) { 744 if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
709 determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, b itmap, 745 determine_clipped_src_rect(fRenderTarget, fClip, viewMatrix, bitmap,
710 srcRectPtr, clippedSrcRect); 746 srcRectPtr, clippedSrcRect);
711 *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize); 747 *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
712 return true; 748 return true;
713 } 749 }
714 750
715 if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTile Size) { 751 if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTile Size) {
716 return false; 752 return false;
717 } 753 }
718 754
719 // if the entire texture is already in our cache then no reason to tile it 755 // if the entire texture is already in our cache then no reason to tile it
720 if (GrIsBitmapInCache(fContext, bitmap, &params)) { 756 if (GrIsBitmapInCache(fContext, bitmap, &params)) {
721 return false; 757 return false;
722 } 758 }
723 759
724 // At this point we know we could do the draw by uploading the entire bitmap 760 // At this point we know we could do the draw by uploading the entire bitmap
725 // as a texture. However, if the texture would be large compared to the 761 // as a texture. However, if the texture would be large compared to the
726 // cache size and we don't require most of it for this draw then tile to 762 // cache size and we don't require most of it for this draw then tile to
727 // reduce the amount of upload and cache spill. 763 // reduce the amount of upload and cache spill.
728 764
729 // assumption here is that sw bitmap size is a good proxy for its size as 765 // assumption here is that sw bitmap size is a good proxy for its size as
730 // a texture 766 // a texture
731 size_t bmpSize = bitmap.getSize(); 767 size_t bmpSize = bitmap.getSize();
732 size_t cacheSize; 768 size_t cacheSize;
733 fContext->getResourceCacheLimits(NULL, &cacheSize); 769 fContext->getResourceCacheLimits(NULL, &cacheSize);
734 if (bmpSize < cacheSize / 2) { 770 if (bmpSize < cacheSize / 2) {
735 return false; 771 return false;
736 } 772 }
737 773
738 // Figure out how much of the src we will need based on the src rect and cli pping. 774 // Figure out how much of the src we will need based on the src rect and cli pping.
739 determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitma p, srcRectPtr, 775 determine_clipped_src_rect(fRenderTarget, fClip, viewMatrix, bitmap, srcRect Ptr,
740 clippedSrcRect); 776 clippedSrcRect);
741 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile. 777 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
742 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) * 778 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
743 kBmpSmallTileSize * kBmpSmallTileSize; 779 kBmpSmallTileSize * kBmpSmallTileSize;
744 780
745 return usedTileBytes < 2 * bmpSize; 781 return usedTileBytes < 2 * bmpSize;
746 } 782 }
747 783
748 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, 784 void SkGpuDevice::drawBitmap(const SkDraw& origDraw,
749 const SkBitmap& bitmap, 785 const SkBitmap& bitmap,
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint *) { 1701 SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint *) {
1666 GrSurfaceDesc desc; 1702 GrSurfaceDesc desc;
1667 desc.fConfig = fRenderTarget->config(); 1703 desc.fConfig = fRenderTarget->config();
1668 desc.fFlags = kRenderTarget_GrSurfaceFlag; 1704 desc.fFlags = kRenderTarget_GrSurfaceFlag;
1669 desc.fWidth = cinfo.fInfo.width(); 1705 desc.fWidth = cinfo.fInfo.width();
1670 desc.fHeight = cinfo.fInfo.height(); 1706 desc.fHeight = cinfo.fInfo.height();
1671 desc.fSampleCnt = fRenderTarget->desc().fSampleCnt; 1707 desc.fSampleCnt = fRenderTarget->desc().fSampleCnt;
1672 1708
1673 SkAutoTUnref<GrTexture> texture; 1709 SkAutoTUnref<GrTexture> texture;
1674 // Skia's convention is to only clear a device if it is non-opaque. 1710 // Skia's convention is to only clear a device if it is non-opaque.
1675 unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag; 1711 InitContents init = cinfo.fInfo.isOpaque() ? kUninit_InitContents : kClear_I nitContents;
1676 1712
1677 // layers are never draw in repeat modes, so we can request an approx 1713 // layers are never draw in repeat modes, so we can request an approx
1678 // match and ignore any padding. 1714 // match and ignore any padding.
1679 const GrTextureProvider::ScratchTexMatch match = (kNever_TileUsage == cinfo. fTileUsage) ? 1715 const GrTextureProvider::ScratchTexMatch match = (kNever_TileUsage == cinfo. fTileUsage) ?
1680 GrTextureProvider::kApprox_Scr atchTexMatch : 1716 GrTextureProvider::kApprox_Scr atchTexMatch :
1681 GrTextureProvider::kExact_Scra tchTexMatch; 1717 GrTextureProvider::kExact_Scra tchTexMatch;
1682 texture.reset(fContext->textureProvider()->refScratchTexture(desc, match)); 1718 texture.reset(fContext->textureProvider()->refScratchTexture(desc, match));
1683 1719
1684 if (texture) { 1720 if (texture) {
1685 SkSurfaceProps props(this->surfaceProps().flags(), cinfo.fPixelGeometry) ; 1721 SkSurfaceProps props(this->surfaceProps().flags(), cinfo.fPixelGeometry) ;
1686 return SkGpuDevice::Create( 1722 return SkGpuDevice::Create(
1687 texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height() , &props, flags); 1723 texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height() , &props, init);
1688 } else { 1724 } else {
1689 SkErrorInternals::SetError( kInternalError_SkError, 1725 SkErrorInternals::SetError( kInternalError_SkError,
1690 "---- failed to create gpu device texture [% d %d]\n", 1726 "---- failed to create gpu device texture [% d %d]\n",
1691 cinfo.fInfo.width(), cinfo.fInfo.height()); 1727 cinfo.fInfo.width(), cinfo.fInfo.height());
1692 return NULL; 1728 return NULL;
1693 } 1729 }
1694 } 1730 }
1695 1731
1696 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps & props) { 1732 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps & props) {
1697 // TODO: Change the signature of newSurface to take a budgeted parameter. 1733 // TODO: Change the signature of newSurface to take a budgeted parameter.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 #endif 1803 #endif
1768 } 1804 }
1769 1805
1770 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { 1806 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
1771 // We always return a transient cache, so it is freed after each 1807 // We always return a transient cache, so it is freed after each
1772 // filter traversal. 1808 // filter traversal.
1773 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); 1809 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
1774 } 1810 }
1775 1811
1776 #endif 1812 #endif
OLDNEW
« no previous file with comments | « src/gpu/SkGpuDevice.h ('k') | src/image/SkImage_Gpu.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698