OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 | 10 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 bool enableDistanceFieldFonts) { | 215 bool enableDistanceFieldFonts) { |
216 if (fGpu->caps()->pathRenderingSupport() && renderTarget->getStencilBuffer()
&& | 216 if (fGpu->caps()->pathRenderingSupport() && renderTarget->getStencilBuffer()
&& |
217 renderTarget->isMultisampled())
{ | 217 renderTarget->isMultisampled())
{ |
218 return GrStencilAndCoverTextContext::Create(this, leakyProperties); | 218 return GrStencilAndCoverTextContext::Create(this, leakyProperties); |
219 } | 219 } |
220 | 220 |
221 return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDista
nceFieldFonts); | 221 return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDista
nceFieldFonts); |
222 } | 222 } |
223 | 223 |
224 //////////////////////////////////////////////////////////////////////////////// | 224 //////////////////////////////////////////////////////////////////////////////// |
| 225 enum ScratchTextureFlags { |
| 226 kExact_ScratchTextureFlag = 0x1, |
| 227 kNoPendingIO_ScratchTextureFlag = 0x2, |
| 228 kNoCreate_ScratchTextureFlag = 0x4, |
| 229 }; |
225 | 230 |
226 bool GrContext::isConfigTexturable(GrPixelConfig config) const { | 231 bool GrContext::isConfigTexturable(GrPixelConfig config) const { |
227 return fGpu->caps()->isConfigTexturable(config); | 232 return fGpu->caps()->isConfigTexturable(config); |
228 } | 233 } |
229 | 234 |
230 bool GrContext::npotTextureTileSupport() const { | 235 bool GrContext::npotTextureTileSupport() const { |
231 return fGpu->caps()->npotTextureTileSupport(); | 236 return fGpu->caps()->npotTextureTileSupport(); |
232 } | 237 } |
233 | 238 |
234 GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, const void* srcDa
ta, | 239 GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, bool budgeted, co
nst void* srcData, |
235 size_t rowBytes) { | 240 size_t rowBytes) { |
236 return fGpu->createTexture(desc, true, srcData, rowBytes); | 241 if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) && |
| 242 !this->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { |
| 243 return NULL; |
| 244 } |
| 245 if (!GrPixelConfigIsCompressed(desc.fConfig)) { |
| 246 static const uint32_t kFlags = kExact_ScratchTextureFlag | |
| 247 kNoCreate_ScratchTextureFlag; |
| 248 if (GrTexture* texture = this->internalRefScratchTexture(desc, kFlags))
{ |
| 249 if (!srcData || texture->writePixels(0, 0, desc.fWidth, desc.fHeight
, desc.fConfig, |
| 250 srcData, rowBytes)) { |
| 251 if (!budgeted) { |
| 252 texture->cacheAccess().makeUnbudgeted(); |
| 253 } |
| 254 return texture; |
| 255 } |
| 256 texture->unref(); |
| 257 } |
| 258 } |
| 259 return fGpu->createTexture(desc, budgeted, srcData, rowBytes); |
237 } | 260 } |
238 | 261 |
239 GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM
atch match, | 262 GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMat
ch match, |
240 bool calledDuringFlush) { | 263 bool calledDuringFlush) { |
241 // Currently we don't recycle compressed textures as scratch. | 264 // Currently we don't recycle compressed textures as scratch. |
242 if (GrPixelConfigIsCompressed(inDesc.fConfig)) { | 265 if (GrPixelConfigIsCompressed(desc.fConfig)) { |
243 return NULL; | 266 return NULL; |
| 267 } else { |
| 268 uint32_t flags = 0; |
| 269 if (kExact_ScratchTexMatch == match) { |
| 270 flags |= kExact_ScratchTextureFlag; |
| 271 } |
| 272 if (calledDuringFlush) { |
| 273 flags |= kNoPendingIO_ScratchTextureFlag; |
| 274 } |
| 275 return this->internalRefScratchTexture(desc, flags); |
244 } | 276 } |
| 277 } |
245 | 278 |
| 279 GrTexture* GrContext::internalRefScratchTexture(const GrSurfaceDesc& inDesc, uin
t32_t flags) { |
| 280 SkASSERT(!GrPixelConfigIsCompressed(inDesc.fConfig)); |
246 // kNoStencil has no meaning if kRT isn't set. | 281 // kNoStencil has no meaning if kRT isn't set. |
247 SkASSERT((inDesc.fFlags & kRenderTarget_GrSurfaceFlag) || | 282 SkASSERT((inDesc.fFlags & kRenderTarget_GrSurfaceFlag) || |
248 !(inDesc.fFlags & kNoStencil_GrSurfaceFlag)); | 283 !(inDesc.fFlags & kNoStencil_GrSurfaceFlag)); |
249 | 284 |
250 // Make sure caller has checked for renderability if kRT is set. | |
251 SkASSERT(!(inDesc.fFlags & kRenderTarget_GrSurfaceFlag) || | |
252 this->isConfigRenderable(inDesc.fConfig, inDesc.fSampleCnt > 0)); | |
253 | |
254 SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc); | 285 SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc); |
255 | 286 |
256 if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_Gr
SurfaceFlag)) { | 287 if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_Gr
SurfaceFlag)) { |
257 GrSurfaceFlags origFlags = desc->fFlags; | 288 GrSurfaceFlags origFlags = desc->fFlags; |
258 if (kApprox_ScratchTexMatch == match) { | 289 if (!(kExact_ScratchTextureFlag & flags)) { |
259 // bin by pow2 with a reasonable min | 290 // bin by pow2 with a reasonable min |
260 static const int MIN_SIZE = 16; | 291 static const int MIN_SIZE = 16; |
261 GrSurfaceDesc* wdesc = desc.writable(); | 292 GrSurfaceDesc* wdesc = desc.writable(); |
262 wdesc->fWidth = SkTMax(MIN_SIZE, GrNextPow2(desc->fWidth)); | 293 wdesc->fWidth = SkTMax(MIN_SIZE, GrNextPow2(desc->fWidth)); |
263 wdesc->fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc->fHeight)); | 294 wdesc->fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc->fHeight)); |
264 } | 295 } |
265 | 296 |
266 do { | 297 do { |
267 GrScratchKey key; | 298 GrScratchKey key; |
268 GrTexturePriv::ComputeScratchKey(*desc, &key); | 299 GrTexturePriv::ComputeScratchKey(*desc, &key); |
269 uint32_t scratchFlags = 0; | 300 uint32_t scratchFlags = 0; |
270 if (calledDuringFlush) { | 301 if (kNoPendingIO_ScratchTextureFlag & flags) { |
271 scratchFlags = GrResourceCache2::kRequireNoPendingIO_ScratchFlag
; | 302 scratchFlags = GrResourceCache2::kRequireNoPendingIO_ScratchFlag
; |
272 } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) { | 303 } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) { |
273 // If it is not a render target then it will most likely be popu
lated by | 304 // If it is not a render target then it will most likely be popu
lated by |
274 // writePixels() which will trigger a flush if the texture has p
ending IO. | 305 // writePixels() which will trigger a flush if the texture has p
ending IO. |
275 scratchFlags = GrResourceCache2::kPreferNoPendingIO_ScratchFlag; | 306 scratchFlags = GrResourceCache2::kPreferNoPendingIO_ScratchFlag; |
276 } | 307 } |
277 GrGpuResource* resource = fResourceCache2->findAndRefScratchResource
(key, scratchFlags); | 308 GrGpuResource* resource = fResourceCache2->findAndRefScratchResource
(key, scratchFlags); |
278 if (resource) { | 309 if (resource) { |
279 GrSurface* surface = static_cast<GrSurface*>(resource); | 310 GrSurface* surface = static_cast<GrSurface*>(resource); |
280 GrRenderTarget* rt = surface->asRenderTarget(); | 311 GrRenderTarget* rt = surface->asRenderTarget(); |
281 if (rt && fGpu->caps()->discardRenderTargetSupport()) { | 312 if (rt && fGpu->caps()->discardRenderTargetSupport()) { |
282 rt->discard(); | 313 rt->discard(); |
283 } | 314 } |
284 return surface->asTexture(); | 315 return surface->asTexture(); |
285 } | 316 } |
286 | 317 |
287 if (kExact_ScratchTexMatch == match) { | 318 if (kExact_ScratchTextureFlag & flags) { |
288 break; | 319 break; |
289 } | 320 } |
290 // We had a cache miss and we are in approx mode, relax the fit of t
he flags. | 321 // We had a cache miss and we are in approx mode, relax the fit of t
he flags. |
291 | 322 |
292 // We no longer try to reuse textures that were previously used as r
ender targets in | 323 // We no longer try to reuse textures that were previously used as r
ender targets in |
293 // situations where no RT is needed; doing otherwise can confuse the
video driver and | 324 // situations where no RT is needed; doing otherwise can confuse the
video driver and |
294 // cause significant performance problems in some cases. | 325 // cause significant performance problems in some cases. |
295 if (desc->fFlags & kNoStencil_GrSurfaceFlag) { | 326 if (desc->fFlags & kNoStencil_GrSurfaceFlag) { |
296 desc.writable()->fFlags = desc->fFlags & ~kNoStencil_GrSurfaceFl
ag; | 327 desc.writable()->fFlags = desc->fFlags & ~kNoStencil_GrSurfaceFl
ag; |
297 } else { | 328 } else { |
298 break; | 329 break; |
299 } | 330 } |
300 | 331 |
301 } while (true); | 332 } while (true); |
302 | 333 |
303 desc.writable()->fFlags = origFlags; | 334 desc.writable()->fFlags = origFlags; |
304 } | 335 } |
305 | 336 |
306 GrTexture* texture = fGpu->createTexture(*desc, true, NULL, 0); | 337 if (!(kNoCreate_ScratchTextureFlag & flags)) { |
307 #ifdef SK_DEBUG | 338 GrTexture* texture = fGpu->createTexture(*desc, true, NULL, 0); |
308 if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_Gr
SurfaceFlag)) { | 339 #ifdef SK_DEBUG |
309 GrScratchKey key; | 340 if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarge
t_GrSurfaceFlag)) { |
310 GrTexturePriv::ComputeScratchKey(*desc, &key); | 341 GrScratchKey key; |
311 SkASSERT(NULL == texture || texture->cacheAccess().getScratchKey() == ke
y); | 342 GrTexturePriv::ComputeScratchKey(*desc, &key); |
| 343 SkASSERT(NULL == texture || texture->cacheAccess().getScratchKey() =
= key); |
| 344 } |
| 345 #endif |
| 346 return texture; |
312 } | 347 } |
313 #endif | 348 |
314 return texture; | 349 return NULL; |
315 } | 350 } |
316 | 351 |
317 void GrContext::OverBudgetCB(void* data) { | 352 void GrContext::OverBudgetCB(void* data) { |
318 SkASSERT(data); | 353 SkASSERT(data); |
319 | 354 |
320 GrContext* context = reinterpret_cast<GrContext*>(data); | 355 GrContext* context = reinterpret_cast<GrContext*>(data); |
321 | 356 |
322 // Flush the InOrderDrawBuffer to possibly free up some textures | 357 // Flush the InOrderDrawBuffer to possibly free up some textures |
323 context->fFlushToReduceCacheSize = true; | 358 context->fFlushToReduceCacheSize = true; |
324 } | 359 } |
325 | 360 |
326 GrTexture* GrContext::createUncachedTexture(const GrSurfaceDesc& desc, | |
327 void* srcData, | |
328 size_t rowBytes) { | |
329 return fGpu->createTexture(desc, false, srcData, rowBytes); | |
330 } | |
331 | |
332 int GrContext::getMaxTextureSize() const { | 361 int GrContext::getMaxTextureSize() const { |
333 return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); | 362 return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); |
334 } | 363 } |
335 | 364 |
336 int GrContext::getMaxRenderTargetSize() const { | 365 int GrContext::getMaxRenderTargetSize() const { |
337 return fGpu->caps()->maxRenderTargetSize(); | 366 return fGpu->caps()->maxRenderTargetSize(); |
338 } | 367 } |
339 | 368 |
340 int GrContext::getMaxSampleCount() const { | 369 int GrContext::getMaxSampleCount() const { |
341 return fGpu->caps()->maxSampleCount(); | 370 return fGpu->caps()->maxSampleCount(); |
(...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 } | 1605 } |
1577 } | 1606 } |
1578 | 1607 |
1579 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { | 1608 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
1580 fGpu->removeGpuTraceMarker(marker); | 1609 fGpu->removeGpuTraceMarker(marker); |
1581 if (fDrawBuffer) { | 1610 if (fDrawBuffer) { |
1582 fDrawBuffer->removeGpuTraceMarker(marker); | 1611 fDrawBuffer->removeGpuTraceMarker(marker); |
1583 } | 1612 } |
1584 } | 1613 } |
1585 | 1614 |
OLD | NEW |