Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "GrCaps.h" | 8 #include "GrCaps.h" |
| 9 #include "GrContext.h" | 9 #include "GrContext.h" |
| 10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 return create_image_from_maker(&maker, at, this->uniqueID()); | 303 return create_image_from_maker(&maker, at, this->uniqueID()); |
| 304 } | 304 } |
| 305 SkBitmap bmp; | 305 SkBitmap bmp; |
| 306 if (!this->asLegacyBitmap(&bmp, kRO_LegacyBitmapMode)) { | 306 if (!this->asLegacyBitmap(&bmp, kRO_LegacyBitmapMode)) { |
| 307 return nullptr; | 307 return nullptr; |
| 308 } | 308 } |
| 309 GrBitmapTextureMaker maker(context, bmp); | 309 GrBitmapTextureMaker maker(context, bmp); |
| 310 return create_image_from_maker(&maker, at, this->uniqueID()); | 310 return create_image_from_maker(&maker, at, this->uniqueID()); |
| 311 } | 311 } |
| 312 | 312 |
| 313 SkImage* SkImage::NewTextureFromPixmap(GrContext* ctx, const SkPixmap& pixmap, | |
| 314 SkBudgeted budgeted) { | |
| 315 if (!ctx) { | |
| 316 return nullptr; | |
| 317 } | |
| 318 SkAutoTUnref<GrTexture> texture(GrUploadPixmapToTexture(ctx, pixmap)); | |
| 319 if (!texture) { | |
| 320 return nullptr; | |
| 321 } | |
| 322 return new SkImage_Gpu(texture->width(), texture->height(), kNeedNewImageUni queID, | |
| 323 pixmap.alphaType(), texture, budgeted); | |
| 324 } | |
| 325 | |
| 326 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 327 | |
| 328 class SkImage::DeferredTextureImage { | |
| 329 public: | |
| 330 SkImage* newImage(GrContext* context, SkBudgeted) const; | |
| 331 | |
| 332 private: | |
| 333 uint32_t fContextUniqueID; | |
| 334 uint32_t fImageUniqueID; | |
| 335 struct Data { | |
| 336 SkImageInfo fInfo; | |
| 337 void* fPixelData; | |
| 338 size_t fRowBytes; | |
| 339 int fColorTableCnt; | |
| 340 uint32_t* fColorTableData; | |
| 341 }; | |
| 342 Data fData; | |
| 343 | |
| 344 friend class SkImage; | |
| 345 static bool GetSizeOrInit(const SkImage* image, const GrContextThreadSafePro xy& proxy, | |
|
robertphillips
2016/03/08 18:43:10
line these up ?
bsalomon
2016/03/08 19:49:32
Done.
| |
| 346 void* inBuffer, size_t inSize, size_t* outSize, | |
| 347 DeferredTextureImage** outDeferredTextureImage); | |
| 348 | |
| 349 }; | |
| 350 | |
| 351 bool SkImage::DeferredTextureImage::GetSizeOrInit(const SkImage* image, | |
| 352 const GrContextThreadSafeProxy& proxy, | |
| 353 void* inBuffer, size_t inSize, size_t* outSize, | |
| 354 SkImage::DeferredTextureImage** outDef erredTextureImage) { | |
| 355 // This function has two modes, (1) querying for the size of the SkImageText ureData, and (2) | |
| 356 // creating the SkImageTextureData in a client buffer. | |
| 357 if (!inBuffer) { | |
| 358 // Mode 1. | |
| 359 if (inSize) { | |
| 360 return false; | |
| 361 } | |
| 362 if (outDeferredTextureImage) { | |
| 363 return false; | |
| 364 } | |
| 365 } else { | |
| 366 // Mode 2. | |
| 367 if (outSize) { | |
| 368 return false; | |
| 369 } | |
| 370 if (!outDeferredTextureImage) { | |
| 371 return false; | |
| 372 } | |
| 373 } | |
| 374 SkAutoPixmapStorage pixmap; | |
| 375 SkImageInfo info; | |
| 376 size_t pixelSize = 0; | |
| 377 size_t ctSize = 0; | |
| 378 int ctCount = 0; | |
| 379 if (image->peekPixels(&pixmap)) { | |
| 380 info = pixmap.info(); | |
| 381 pixelSize = SkAlign8(pixmap.getSafeSize()); | |
| 382 if (pixmap.ctable()) { | |
| 383 ctCount = pixmap.ctable()->count(); | |
| 384 ctSize = SkAlign8(pixmap.ctable()->count() * 4); | |
| 385 } | |
| 386 } else { | |
| 387 // Here we're just using presence of data to know whether there is a cod ec behind the image. | |
| 388 // In the future we will access the cacherator and get the exact data th at we want to (e.g. | |
| 389 // yuv planes) upload. | |
| 390 SkAutoTUnref<SkData> data(image->refEncoded()); | |
| 391 if (!data) { | |
|
robertphillips
2016/03/08 18:43:10
too far over ?
bsalomon
2016/03/08 19:49:32
Done.
| |
| 392 return false; | |
| 393 } | |
| 394 SkAlphaType at = image->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlp haType; | |
| 395 info = SkImageInfo::MakeN32(image->width(), image->height(), at); | |
| 396 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); | |
| 397 if (inBuffer) { | |
| 398 pixmap.alloc(info); | |
| 399 if (!image->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint) ) { | |
| 400 return false; | |
| 401 } | |
| 402 SkASSERT(!pixmap.ctable()); | |
| 403 } | |
| 404 } | |
| 405 size_t size = 0; | |
|
robertphillips
2016/03/08 18:43:10
is this supposed to be dtiSize ?
bsalomon
2016/03/08 19:49:32
Done.
| |
| 406 size_t itdSize = SkAlign8(sizeof(DeferredTextureImage)); | |
| 407 size += itdSize; | |
| 408 size_t pixelOffset = size; | |
| 409 size += pixelSize; | |
| 410 size_t ctOffset = size; | |
| 411 size += ctSize; | |
| 412 if (!inBuffer) { | |
| 413 *outSize = size; | |
| 414 return true; | |
| 415 } else if (inSize < size) { | |
| 416 return false; | |
| 417 } | |
| 418 intptr_t allocation = reinterpret_cast<intptr_t>(inBuffer); | |
|
robertphillips
2016/03/08 18:43:10
itd -> dti ?
bsalomon
2016/03/08 19:49:32
Done.
| |
| 419 void* itd = reinterpret_cast<void*>(allocation); | |
| 420 void* pixels = reinterpret_cast<void*>(allocation + pixelOffset); | |
| 421 SkPMColor* ct = nullptr; | |
| 422 if (ctSize) { | |
| 423 ct = reinterpret_cast<SkPMColor*>(allocation + ctOffset); | |
| 424 } | |
| 425 | |
| 426 memcpy(pixels, pixmap.addr(), pixmap.getSafeSize()); | |
| 427 if (ctSize) { | |
| 428 memcpy(ct, pixmap.ctable()->readColors(), ctSize); | |
| 429 } | |
| 430 | |
| 431 SkASSERT(info == pixmap.info()); | |
| 432 size_t rowBytes = pixmap.rowBytes(); | |
| 433 (*outDeferredTextureImage) = new (itd) DeferredTextureImage(); | |
| 434 (*outDeferredTextureImage)->fContextUniqueID = proxy.fContextUniqueID; | |
| 435 (*outDeferredTextureImage)->fImageUniqueID = image->uniqueID(); | |
| 436 (*outDeferredTextureImage)->fData.fInfo = info; | |
| 437 (*outDeferredTextureImage)->fData.fPixelData = pixels; | |
| 438 (*outDeferredTextureImage)->fData.fRowBytes = rowBytes; | |
| 439 (*outDeferredTextureImage)->fData.fColorTableCnt = ctCount; | |
| 440 (*outDeferredTextureImage)->fData.fColorTableData = ct; | |
| 441 return true; | |
| 442 } | |
| 443 | |
| 444 size_t SkImage::getDeferredTextureImageSize(const GrContextThreadSafeProxy& prox y, | |
| 445 const DeferredTextureImageUsageParam s[], | |
| 446 int paramCnt) const { | |
| 447 size_t size; | |
| 448 if (DeferredTextureImage::GetSizeOrInit(this, proxy, nullptr, 0, &size, null ptr)) { | |
| 449 return size; | |
| 450 } | |
| 451 return 0; | |
| 452 } | |
| 453 | |
| 454 const SkImage::DeferredTextureImage* SkImage::createDeferredTextureImageInClient Storage( | |
| 455 const GrContextThreadSafeProxy& proxy, | |
| 456 const DeferredTextureImageUsageParams[], int paramCnt, | |
| 457 void* buffer, size_t bufferSize) const { | |
| 458 DeferredTextureImage* deferredTextureImage; | |
| 459 if (DeferredTextureImage::GetSizeOrInit(this, proxy, buffer, bufferSize, nul lptr, | |
| 460 &deferredTextureImage)) { | |
| 461 return deferredTextureImage; | |
| 462 } | |
| 463 return nullptr; | |
| 464 } | |
| 465 | |
| 466 SkImage* SkImage::NewFromDeferredTextureImage(GrContext* context, const Deferred TextureImage& dti, | |
| 467 SkBudgeted budgeted) { | |
| 468 if (!context || context->uniqueID() != dti.fContextUniqueID) { | |
| 469 return nullptr; | |
| 470 } | |
| 471 SkAutoTUnref<SkColorTable> colorTable; | |
| 472 if (dti.fData.fColorTableCnt) { | |
| 473 SkASSERT(dti.fData.fColorTableData); | |
| 474 colorTable.reset(new SkColorTable(dti.fData.fColorTableData, dti.fData.f ColorTableCnt)); | |
| 475 } | |
| 476 SkPixmap pixmap; | |
| 477 pixmap.reset(dti.fData.fInfo, dti.fData.fPixelData, dti.fData.fRowBytes, col orTable.get()); | |
| 478 return SkImage::NewTextureFromPixmap(context, pixmap, budgeted); | |
| 479 } | |
| 480 | |
| 313 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 481 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 314 | 482 |
| 315 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) { | 483 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) { |
| 316 GrContext* ctx = src->getContext(); | 484 GrContext* ctx = src->getContext(); |
| 317 | 485 |
| 318 GrSurfaceDesc desc = src->desc(); | 486 GrSurfaceDesc desc = src->desc(); |
| 319 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0); | 487 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0); |
| 320 if (!dst) { | 488 if (!dst) { |
| 321 return nullptr; | 489 return nullptr; |
| 322 } | 490 } |
| 323 | 491 |
| 324 const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight); | 492 const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight); |
| 325 const SkIPoint dstP = SkIPoint::Make(0, 0); | 493 const SkIPoint dstP = SkIPoint::Make(0, 0); |
| 326 ctx->copySurface(dst, src, srcR, dstP); | 494 ctx->copySurface(dst, src, srcR, dstP); |
| 327 ctx->flushSurfaceWrites(dst); | 495 ctx->flushSurfaceWrites(dst); |
| 328 return dst; | 496 return dst; |
| 329 } | 497 } |
| 330 | 498 |
| OLD | NEW |