GrBackendSurface.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. /*
  2. * Copyright 2017 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/gpu/GrBackendSurface.h"
  8. #include "src/gpu/gl/GrGLUtil.h"
  9. #ifdef SK_DAWN
  10. #include "include/gpu/dawn/GrDawnTypes.h"
  11. #include "src/gpu/dawn/GrDawnUtil.h"
  12. #endif
  13. #ifdef SK_VULKAN
  14. #include "include/gpu/vk/GrVkTypes.h"
  15. #include "src/gpu/vk/GrVkImageLayout.h"
  16. #include "src/gpu/vk/GrVkUtil.h"
  17. #endif
  18. #ifdef SK_METAL
  19. #include "include/gpu/mtl/GrMtlTypes.h"
  20. #include "src/gpu/mtl/GrMtlCppUtil.h"
  21. #endif
  22. GrBackendFormat::GrBackendFormat(const GrBackendFormat& that)
  23. : fBackend(that.fBackend)
  24. , fValid(that.fValid)
  25. , fTextureType(that.fTextureType) {
  26. if (!fValid) {
  27. return;
  28. }
  29. switch (fBackend) {
  30. #ifdef SK_GL
  31. case GrBackendApi::kOpenGL:
  32. fGLFormat = that.fGLFormat;
  33. break;
  34. #endif
  35. #ifdef SK_VULKAN
  36. case GrBackendApi::kVulkan:
  37. fVk = that.fVk;
  38. break;
  39. #endif
  40. #ifdef SK_METAL
  41. case GrBackendApi::kMetal:
  42. fMtlFormat = that.fMtlFormat;
  43. break;
  44. #endif
  45. #ifdef SK_DAWN
  46. case GrBackendApi::kDawn:
  47. fDawnFormat = that.fDawnFormat;
  48. break;
  49. #endif
  50. case GrBackendApi::kMock:
  51. fMockColorType = that.fMockColorType;
  52. break;
  53. default:
  54. SK_ABORT("Unknown GrBackend");
  55. }
  56. }
  57. GrBackendFormat::GrBackendFormat(GrGLenum format, GrGLenum target)
  58. : fBackend(GrBackendApi::kOpenGL)
  59. , fValid(true)
  60. , fGLFormat(format) {
  61. switch (target) {
  62. case GR_GL_TEXTURE_NONE:
  63. fTextureType = GrTextureType::kNone;
  64. break;
  65. case GR_GL_TEXTURE_2D:
  66. fTextureType = GrTextureType::k2D;
  67. break;
  68. case GR_GL_TEXTURE_RECTANGLE:
  69. fTextureType = GrTextureType::kRectangle;
  70. break;
  71. case GR_GL_TEXTURE_EXTERNAL:
  72. fTextureType = GrTextureType::kExternal;
  73. break;
  74. default:
  75. SK_ABORT("Unexpected texture target");
  76. }
  77. }
  78. const GrGLenum* GrBackendFormat::getGLFormat() const {
  79. if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
  80. return &fGLFormat;
  81. }
  82. return nullptr;
  83. }
  84. const GrGLenum* GrBackendFormat::getGLTarget() const {
  85. if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
  86. static constexpr GrGLenum kNone = GR_GL_TEXTURE_NONE;
  87. static constexpr GrGLenum k2D = GR_GL_TEXTURE_2D;
  88. static constexpr GrGLenum kRect = GR_GL_TEXTURE_RECTANGLE;
  89. static constexpr GrGLenum kExternal = GR_GL_TEXTURE_EXTERNAL;
  90. switch (fTextureType) {
  91. case GrTextureType::kNone:
  92. return &kNone;
  93. case GrTextureType::k2D:
  94. return &k2D;
  95. case GrTextureType::kRectangle:
  96. return &kRect;
  97. case GrTextureType::kExternal:
  98. return &kExternal;
  99. }
  100. }
  101. return nullptr;
  102. }
  103. GrBackendFormat GrBackendFormat::MakeVk(const GrVkYcbcrConversionInfo& ycbcrInfo) {
  104. #ifdef SK_BUILD_FOR_ANDROID
  105. return GrBackendFormat(VK_FORMAT_UNDEFINED, ycbcrInfo);
  106. #else
  107. return GrBackendFormat();
  108. #endif
  109. }
  110. GrBackendFormat::GrBackendFormat(VkFormat vkFormat, const GrVkYcbcrConversionInfo& ycbcrInfo)
  111. : fBackend(GrBackendApi::kVulkan)
  112. #ifdef SK_VULKAN
  113. , fValid(true)
  114. #else
  115. , fValid(false)
  116. #endif
  117. , fTextureType(GrTextureType::k2D) {
  118. fVk.fFormat = vkFormat;
  119. fVk.fYcbcrConversionInfo = ycbcrInfo;
  120. if (fVk.fYcbcrConversionInfo.isValid()) {
  121. fTextureType = GrTextureType::kExternal;
  122. }
  123. }
  124. const VkFormat* GrBackendFormat::getVkFormat() const {
  125. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  126. return &fVk.fFormat;
  127. }
  128. return nullptr;
  129. }
  130. const GrVkYcbcrConversionInfo* GrBackendFormat::getVkYcbcrConversionInfo() const {
  131. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  132. return &fVk.fYcbcrConversionInfo;
  133. }
  134. return nullptr;
  135. }
  136. #ifdef SK_DAWN
  137. GrBackendFormat::GrBackendFormat(dawn::TextureFormat format)
  138. : fBackend(GrBackendApi::kDawn)
  139. , fValid(true)
  140. , fDawnFormat(format)
  141. , fTextureType(GrTextureType::k2D) {
  142. }
  143. const dawn::TextureFormat* GrBackendFormat::getDawnFormat() const {
  144. if (this->isValid() && GrBackendApi::kDawn == fBackend) {
  145. return &fDawnFormat;
  146. }
  147. return nullptr;
  148. }
  149. #endif
  150. #ifdef SK_METAL
  151. GrBackendFormat::GrBackendFormat(GrMTLPixelFormat mtlFormat)
  152. : fBackend(GrBackendApi::kMetal)
  153. , fValid(true)
  154. , fMtlFormat(mtlFormat)
  155. , fTextureType(GrTextureType::k2D) {
  156. }
  157. const GrMTLPixelFormat* GrBackendFormat::getMtlFormat() const {
  158. if (this->isValid() && GrBackendApi::kMetal == fBackend) {
  159. return &fMtlFormat;
  160. }
  161. return nullptr;
  162. }
  163. #endif
  164. GrBackendFormat::GrBackendFormat(GrColorType colorType)
  165. : fBackend(GrBackendApi::kMock)
  166. , fValid(true)
  167. , fTextureType(GrTextureType::k2D) {
  168. fMockColorType = colorType;
  169. }
  170. const GrColorType* GrBackendFormat::getMockColorType() const {
  171. if (this->isValid() && GrBackendApi::kMock == fBackend) {
  172. return &fMockColorType;
  173. }
  174. return nullptr;
  175. }
  176. GrBackendFormat GrBackendFormat::makeTexture2D() const {
  177. GrBackendFormat copy = *this;
  178. if (const GrVkYcbcrConversionInfo* ycbcrInfo = this->getVkYcbcrConversionInfo()) {
  179. if (ycbcrInfo->isValid()) {
  180. // If we have a ycbcr we remove it from the backend format and set the VkFormat to
  181. // R8G8B8A8_UNORM
  182. SkASSERT(copy.fBackend == GrBackendApi::kVulkan);
  183. copy.fVk.fYcbcrConversionInfo = GrVkYcbcrConversionInfo();
  184. copy.fVk.fFormat = VK_FORMAT_R8G8B8A8_UNORM;
  185. }
  186. }
  187. copy.fTextureType = GrTextureType::k2D;
  188. return copy;
  189. }
  190. bool GrBackendFormat::operator==(const GrBackendFormat& that) const {
  191. // Invalid GrBackendFormats are never equal to anything.
  192. if (!fValid || !that.fValid) {
  193. return false;
  194. }
  195. if (fBackend != that.fBackend) {
  196. return false;
  197. }
  198. switch (fBackend) {
  199. case GrBackendApi::kOpenGL:
  200. return fGLFormat == that.fGLFormat;
  201. case GrBackendApi::kVulkan:
  202. #ifdef SK_VULKAN
  203. return fVk.fFormat == that.fVk.fFormat &&
  204. fVk.fYcbcrConversionInfo == that.fVk.fYcbcrConversionInfo;
  205. #endif
  206. break;
  207. #ifdef SK_METAL
  208. case GrBackendApi::kMetal:
  209. return fMtlFormat == that.fMtlFormat;
  210. #endif
  211. break;
  212. case GrBackendApi::kDawn:
  213. #ifdef SK_DAWN
  214. return fDawnFormat == that.fDawnFormat;
  215. #endif
  216. break;
  217. case GrBackendApi::kMock:
  218. return fMockColorType == that.fMockColorType;
  219. default:
  220. SK_ABORT("Unknown GrBackend");
  221. }
  222. return false;
  223. }
  224. #ifdef SK_DAWN
  225. GrBackendTexture::GrBackendTexture(int width,
  226. int height,
  227. const GrDawnImageInfo& dawnInfo)
  228. : fIsValid(true)
  229. , fWidth(width)
  230. , fHeight(height)
  231. , fConfig(GrDawnFormatToPixelConfig(dawnInfo.fFormat))
  232. , fMipMapped(GrMipMapped(dawnInfo.fLevelCount > 1))
  233. , fBackend(GrBackendApi::kDawn)
  234. , fDawnInfo(dawnInfo) {}
  235. #endif
  236. GrBackendTexture::GrBackendTexture(int width, int height, const GrVkImageInfo& vkInfo)
  237. #ifdef SK_VULKAN
  238. : GrBackendTexture(width, height, vkInfo,
  239. sk_sp<GrVkImageLayout>(new GrVkImageLayout(vkInfo.fImageLayout))) {}
  240. #else
  241. : fIsValid(false) {}
  242. #endif
  243. #ifdef SK_GL
  244. GrBackendTexture::GrBackendTexture(int width,
  245. int height,
  246. GrMipMapped mipMapped,
  247. const GrGLTextureInfo glInfo,
  248. sk_sp<GrGLTextureParameters> params)
  249. : fIsValid(true)
  250. , fWidth(width)
  251. , fHeight(height)
  252. , fConfig(kUnknown_GrPixelConfig)
  253. , fMipMapped(mipMapped)
  254. , fBackend(GrBackendApi::kOpenGL)
  255. , fGLInfo(glInfo, params.release()) {}
  256. sk_sp<GrGLTextureParameters> GrBackendTexture::getGLTextureParams() const {
  257. if (fBackend != GrBackendApi::kOpenGL) {
  258. return nullptr;
  259. }
  260. return fGLInfo.refParameters();
  261. }
  262. #endif
  263. #ifdef SK_VULKAN
  264. GrBackendTexture::GrBackendTexture(int width,
  265. int height,
  266. const GrVkImageInfo& vkInfo,
  267. sk_sp<GrVkImageLayout> layout)
  268. : fIsValid(true)
  269. , fWidth(width)
  270. , fHeight(height)
  271. , fConfig(kUnknown_GrPixelConfig)
  272. , fMipMapped(GrMipMapped(vkInfo.fLevelCount > 1))
  273. , fBackend(GrBackendApi::kVulkan)
  274. , fVkInfo(vkInfo, layout.release()) {}
  275. #endif
  276. #ifdef SK_METAL
  277. GrBackendTexture::GrBackendTexture(int width,
  278. int height,
  279. GrMipMapped mipMapped,
  280. const GrMtlTextureInfo& mtlInfo)
  281. : fIsValid(true)
  282. , fWidth(width)
  283. , fHeight(height)
  284. , fConfig(GrPixelConfig::kUnknown_GrPixelConfig)
  285. , fMipMapped(mipMapped)
  286. , fBackend(GrBackendApi::kMetal)
  287. , fMtlInfo(mtlInfo) {}
  288. #endif
  289. GrBackendTexture::GrBackendTexture(int width,
  290. int height,
  291. GrMipMapped mipMapped,
  292. const GrGLTextureInfo& glInfo)
  293. : GrBackendTexture(width, height, mipMapped, glInfo, sk_make_sp<GrGLTextureParameters>()) {
  294. // Make no assumptions about client's texture's parameters.
  295. this->glTextureParametersModified();
  296. }
  297. GrBackendTexture::GrBackendTexture(int width,
  298. int height,
  299. GrMipMapped mipMapped,
  300. const GrMockTextureInfo& mockInfo)
  301. : fIsValid(true)
  302. , fWidth(width)
  303. , fHeight(height)
  304. , fConfig(mockInfo.pixelConfig())
  305. , fMipMapped(mipMapped)
  306. , fBackend(GrBackendApi::kMock)
  307. , fMockInfo(mockInfo) {}
  308. GrBackendTexture::~GrBackendTexture() {
  309. this->cleanup();
  310. }
  311. void GrBackendTexture::cleanup() {
  312. #ifdef SK_GL
  313. if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
  314. fGLInfo.cleanup();
  315. }
  316. #endif
  317. #ifdef SK_VULKAN
  318. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  319. fVkInfo.cleanup();
  320. }
  321. #endif
  322. }
  323. GrBackendTexture::GrBackendTexture(const GrBackendTexture& that) : fIsValid(false) {
  324. *this = that;
  325. }
  326. GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
  327. if (!that.isValid()) {
  328. this->cleanup();
  329. fIsValid = false;
  330. return *this;
  331. } else if (fIsValid && this->fBackend != that.fBackend) {
  332. this->cleanup();
  333. fIsValid = false;
  334. }
  335. fWidth = that.fWidth;
  336. fHeight = that.fHeight;
  337. fConfig = that.fConfig;
  338. fMipMapped = that.fMipMapped;
  339. fBackend = that.fBackend;
  340. switch (that.fBackend) {
  341. #ifdef SK_GL
  342. case GrBackendApi::kOpenGL:
  343. fGLInfo.assign(that.fGLInfo, this->isValid());
  344. break;
  345. #endif
  346. #ifdef SK_VULKAN
  347. case GrBackendApi::kVulkan:
  348. fVkInfo.assign(that.fVkInfo, this->isValid());
  349. break;
  350. #endif
  351. #ifdef SK_METAL
  352. case GrBackendApi::kMetal:
  353. fMtlInfo = that.fMtlInfo;
  354. break;
  355. #endif
  356. #ifdef SK_DAWN
  357. case GrBackendApi::kDawn:
  358. fDawnInfo = that.fDawnInfo;
  359. break;
  360. #endif
  361. case GrBackendApi::kMock:
  362. fMockInfo = that.fMockInfo;
  363. break;
  364. default:
  365. SK_ABORT("Unknown GrBackend");
  366. }
  367. fIsValid = true;
  368. return *this;
  369. }
  370. #ifdef SK_DAWN
  371. bool GrBackendTexture::getDawnImageInfo(GrDawnImageInfo* outInfo) const {
  372. if (this->isValid() && GrBackendApi::kDawn == fBackend) {
  373. *outInfo = fDawnInfo;
  374. return true;
  375. }
  376. return false;
  377. }
  378. #endif
  379. bool GrBackendTexture::getVkImageInfo(GrVkImageInfo* outInfo) const {
  380. #ifdef SK_VULKAN
  381. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  382. *outInfo = fVkInfo.snapImageInfo();
  383. return true;
  384. }
  385. #endif
  386. return false;
  387. }
  388. void GrBackendTexture::setVkImageLayout(VkImageLayout layout) {
  389. #ifdef SK_VULKAN
  390. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  391. fVkInfo.setImageLayout(layout);
  392. }
  393. #endif
  394. }
  395. #ifdef SK_VULKAN
  396. sk_sp<GrVkImageLayout> GrBackendTexture::getGrVkImageLayout() const {
  397. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  398. return fVkInfo.getGrVkImageLayout();
  399. }
  400. return nullptr;
  401. }
  402. #endif
  403. #ifdef SK_METAL
  404. bool GrBackendTexture::getMtlTextureInfo(GrMtlTextureInfo* outInfo) const {
  405. if (this->isValid() && GrBackendApi::kMetal == fBackend) {
  406. *outInfo = fMtlInfo;
  407. return true;
  408. }
  409. return false;
  410. }
  411. #endif
  412. bool GrBackendTexture::getGLTextureInfo(GrGLTextureInfo* outInfo) const {
  413. #ifdef SK_GL
  414. if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
  415. *outInfo = fGLInfo.info();
  416. return true;
  417. } else if (this->isValid() && GrBackendApi::kMock == fBackend) {
  418. // Hack! This allows some blink unit tests to work when using the Mock GrContext.
  419. // Specifically, tests that rely on CanvasResourceProviderTextureGpuMemoryBuffer.
  420. // If that code ever goes away (or ideally becomes backend-agnostic), this can go away.
  421. *outInfo = GrGLTextureInfo{ GR_GL_TEXTURE_2D,
  422. static_cast<GrGLuint>(fMockInfo.fID),
  423. GR_GL_RGBA8 };
  424. return true;
  425. }
  426. #endif
  427. return false;
  428. }
  429. void GrBackendTexture::glTextureParametersModified() {
  430. #ifdef SK_GL
  431. if (this->isValid() && fBackend == GrBackendApi::kOpenGL) {
  432. fGLInfo.parameters()->invalidate();
  433. }
  434. #endif
  435. }
  436. bool GrBackendTexture::getMockTextureInfo(GrMockTextureInfo* outInfo) const {
  437. if (this->isValid() && GrBackendApi::kMock == fBackend) {
  438. *outInfo = fMockInfo;
  439. return true;
  440. }
  441. return false;
  442. }
  443. bool GrBackendTexture::isProtected() const {
  444. if (!this->isValid() || this->backend() != GrBackendApi::kVulkan) {
  445. return false;
  446. }
  447. return fVkInfo.isProtected();
  448. }
  449. bool GrBackendTexture::isSameTexture(const GrBackendTexture& that) {
  450. if (!this->isValid() || !that.isValid()) {
  451. return false;
  452. }
  453. if (fBackend != that.fBackend) {
  454. return false;
  455. }
  456. switch (fBackend) {
  457. #ifdef SK_GL
  458. case GrBackendApi::kOpenGL:
  459. return fGLInfo.info().fID == that.fGLInfo.info().fID;
  460. #endif
  461. #ifdef SK_VULKAN
  462. case GrBackendApi::kVulkan:
  463. return fVkInfo.snapImageInfo().fImage == that.fVkInfo.snapImageInfo().fImage;
  464. #endif
  465. #ifdef SK_METAL
  466. case GrBackendApi::kMetal:
  467. return this->fMtlInfo.fTexture == that.fMtlInfo.fTexture;
  468. #endif
  469. case GrBackendApi::kMock:
  470. return fMockInfo.fID == that.fMockInfo.fID;
  471. default:
  472. return false;
  473. }
  474. }
  475. GrBackendFormat GrBackendTexture::getBackendFormat() const {
  476. if (!this->isValid()) {
  477. return GrBackendFormat();
  478. }
  479. switch (fBackend) {
  480. #ifdef SK_GL
  481. case GrBackendApi::kOpenGL:
  482. return GrBackendFormat::MakeGL(fGLInfo.info().fFormat, fGLInfo.info().fTarget);
  483. #endif
  484. #ifdef SK_VULKAN
  485. case GrBackendApi::kVulkan: {
  486. auto info = fVkInfo.snapImageInfo();
  487. if (info.fYcbcrConversionInfo.isValid()) {
  488. SkASSERT(info.fFormat == VK_FORMAT_UNDEFINED);
  489. return GrBackendFormat::MakeVk(info.fYcbcrConversionInfo);
  490. }
  491. return GrBackendFormat::MakeVk(info.fFormat);
  492. }
  493. #endif
  494. #ifdef SK_DAWN
  495. case GrBackendApi::kDawn: {
  496. return GrBackendFormat::MakeDawn(fDawnInfo.fFormat);
  497. }
  498. #endif
  499. #ifdef SK_METAL
  500. case GrBackendApi::kMetal: {
  501. GrMtlTextureInfo mtlInfo;
  502. SkAssertResult(this->getMtlTextureInfo(&mtlInfo));
  503. return GrBackendFormat::MakeMtl(GrGetMTLPixelFormatFromMtlTextureInfo(mtlInfo));
  504. }
  505. #endif
  506. case GrBackendApi::kMock:
  507. return fMockInfo.getBackendFormat();
  508. default:
  509. return GrBackendFormat();
  510. }
  511. }
  512. #if GR_TEST_UTILS
  513. bool GrBackendTexture::TestingOnly_Equals(const GrBackendTexture& t0, const GrBackendTexture& t1) {
  514. if (!t0.isValid() || !t1.isValid()) {
  515. return false; // two invalid backend textures are not considered equal
  516. }
  517. if (t0.fWidth != t1.fWidth ||
  518. t0.fHeight != t1.fHeight ||
  519. t0.fConfig != t1.fConfig ||
  520. t0.fMipMapped != t1.fMipMapped ||
  521. t0.fBackend != t1.fBackend) {
  522. return false;
  523. }
  524. switch (t0.fBackend) {
  525. #ifdef SK_GL
  526. case GrBackendApi::kOpenGL:
  527. return t0.fGLInfo.info() == t1.fGLInfo.info();
  528. #endif
  529. case GrBackendApi::kMock:
  530. return t0.fMockInfo == t1.fMockInfo;
  531. #ifdef SK_VULKAN
  532. case GrBackendApi::kVulkan:
  533. return t0.fVkInfo == t1.fVkInfo;
  534. #endif
  535. #ifdef SK_METAL
  536. case GrBackendApi::kMetal:
  537. return t0.fMtlInfo == t1.fMtlInfo;
  538. #endif
  539. #ifdef SK_DAWN
  540. case GrBackendApi::kDawn:
  541. return t0.fDawnInfo == t1.fDawnInfo;
  542. #endif
  543. default:
  544. return false;
  545. }
  546. }
  547. #endif
  548. ////////////////////////////////////////////////////////////////////////////////////////////////////
  549. #ifdef SK_DAWN
  550. GrBackendRenderTarget::GrBackendRenderTarget(int width,
  551. int height,
  552. int sampleCnt,
  553. int stencilBits,
  554. const GrDawnImageInfo& dawnInfo)
  555. : fIsValid(true)
  556. , fWidth(width)
  557. , fHeight(height)
  558. , fSampleCnt(sampleCnt)
  559. , fStencilBits(stencilBits)
  560. , fConfig(GrDawnFormatToPixelConfig(dawnInfo.fFormat))
  561. , fBackend(GrBackendApi::kDawn)
  562. , fDawnInfo(dawnInfo) {}
  563. #endif
  564. GrBackendRenderTarget::GrBackendRenderTarget(int width,
  565. int height,
  566. int sampleCnt,
  567. int stencilBits,
  568. const GrVkImageInfo& vkInfo)
  569. : GrBackendRenderTarget(width, height, sampleCnt, vkInfo) {
  570. // This is a deprecated constructor that takes a bogus stencil bits.
  571. SkASSERT(0 == stencilBits);
  572. }
  573. GrBackendRenderTarget::GrBackendRenderTarget(int width,
  574. int height,
  575. int sampleCnt,
  576. const GrVkImageInfo& vkInfo)
  577. #ifdef SK_VULKAN
  578. : GrBackendRenderTarget(width, height, sampleCnt, vkInfo,
  579. sk_sp<GrVkImageLayout>(new GrVkImageLayout(vkInfo.fImageLayout))) {}
  580. #else
  581. : fIsValid(false) {}
  582. #endif
  583. #ifdef SK_VULKAN
  584. GrBackendRenderTarget::GrBackendRenderTarget(int width,
  585. int height,
  586. int sampleCnt,
  587. const GrVkImageInfo& vkInfo,
  588. sk_sp<GrVkImageLayout> layout)
  589. : fIsValid(true)
  590. , fWidth(width)
  591. , fHeight(height)
  592. , fSampleCnt(SkTMax(1, sampleCnt))
  593. , fStencilBits(0) // We always create stencil buffers internally for vulkan
  594. , fConfig(kUnknown_GrPixelConfig)
  595. , fBackend(GrBackendApi::kVulkan)
  596. , fVkInfo(vkInfo, layout.release()) {}
  597. #endif
  598. #ifdef SK_METAL
  599. GrBackendRenderTarget::GrBackendRenderTarget(int width,
  600. int height,
  601. int sampleCnt,
  602. const GrMtlTextureInfo& mtlInfo)
  603. : fIsValid(true)
  604. , fWidth(width)
  605. , fHeight(height)
  606. , fSampleCnt(SkTMax(1, sampleCnt))
  607. , fStencilBits(0)
  608. , fConfig(GrPixelConfig::kUnknown_GrPixelConfig)
  609. , fBackend(GrBackendApi::kMetal)
  610. , fMtlInfo(mtlInfo) {}
  611. #endif
  612. GrBackendRenderTarget::GrBackendRenderTarget(int width,
  613. int height,
  614. int sampleCnt,
  615. int stencilBits,
  616. const GrGLFramebufferInfo& glInfo)
  617. : fWidth(width)
  618. , fHeight(height)
  619. , fSampleCnt(SkTMax(1, sampleCnt))
  620. , fStencilBits(stencilBits)
  621. , fConfig(kUnknown_GrPixelConfig)
  622. , fBackend(GrBackendApi::kOpenGL)
  623. , fGLInfo(glInfo) {
  624. fIsValid = SkToBool(glInfo.fFormat); // the glInfo must have a valid format
  625. }
  626. GrBackendRenderTarget::GrBackendRenderTarget(int width,
  627. int height,
  628. int sampleCnt,
  629. int stencilBits,
  630. const GrMockRenderTargetInfo& mockInfo)
  631. : fIsValid(true)
  632. , fWidth(width)
  633. , fHeight(height)
  634. , fSampleCnt(SkTMax(1, sampleCnt))
  635. , fStencilBits(stencilBits)
  636. , fConfig(mockInfo.pixelConfig())
  637. , fMockInfo(mockInfo) {}
  638. GrBackendRenderTarget::~GrBackendRenderTarget() {
  639. this->cleanup();
  640. }
  641. void GrBackendRenderTarget::cleanup() {
  642. #ifdef SK_VULKAN
  643. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  644. fVkInfo.cleanup();
  645. }
  646. #endif
  647. }
  648. GrBackendRenderTarget::GrBackendRenderTarget(const GrBackendRenderTarget& that) : fIsValid(false) {
  649. *this = that;
  650. }
  651. GrBackendRenderTarget& GrBackendRenderTarget::operator=(const GrBackendRenderTarget& that) {
  652. if (!that.isValid()) {
  653. this->cleanup();
  654. fIsValid = false;
  655. return *this;
  656. } else if (fIsValid && this->fBackend != that.fBackend) {
  657. this->cleanup();
  658. fIsValid = false;
  659. }
  660. fWidth = that.fWidth;
  661. fHeight = that.fHeight;
  662. fSampleCnt = that.fSampleCnt;
  663. fStencilBits = that.fStencilBits;
  664. fConfig = that.fConfig;
  665. fBackend = that.fBackend;
  666. switch (that.fBackend) {
  667. case GrBackendApi::kOpenGL:
  668. fGLInfo = that.fGLInfo;
  669. break;
  670. case GrBackendApi::kVulkan:
  671. #ifdef SK_VULKAN
  672. fVkInfo.assign(that.fVkInfo, this->isValid());
  673. #endif
  674. break;
  675. #ifdef SK_DAWN
  676. case GrBackendApi::kDawn:
  677. fDawnInfo = that.fDawnInfo;
  678. break;
  679. #endif
  680. #ifdef SK_METAL
  681. case GrBackendApi::kMetal:
  682. fMtlInfo = that.fMtlInfo;
  683. break;
  684. #endif
  685. case GrBackendApi::kMock:
  686. fMockInfo = that.fMockInfo;
  687. break;
  688. default:
  689. SK_ABORT("Unknown GrBackend");
  690. }
  691. fIsValid = that.fIsValid;
  692. return *this;
  693. }
  694. #ifdef SK_DAWN
  695. bool GrBackendRenderTarget::getDawnImageInfo(GrDawnImageInfo* outInfo) const {
  696. if (this->isValid() && GrBackendApi::kDawn == fBackend) {
  697. *outInfo = fDawnInfo;
  698. return true;
  699. }
  700. return false;
  701. }
  702. #endif
  703. bool GrBackendRenderTarget::getVkImageInfo(GrVkImageInfo* outInfo) const {
  704. #ifdef SK_VULKAN
  705. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  706. *outInfo = fVkInfo.snapImageInfo();
  707. return true;
  708. }
  709. #endif
  710. return false;
  711. }
  712. void GrBackendRenderTarget::setVkImageLayout(VkImageLayout layout) {
  713. #ifdef SK_VULKAN
  714. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  715. fVkInfo.setImageLayout(layout);
  716. }
  717. #endif
  718. }
  719. #ifdef SK_VULKAN
  720. sk_sp<GrVkImageLayout> GrBackendRenderTarget::getGrVkImageLayout() const {
  721. if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
  722. return fVkInfo.getGrVkImageLayout();
  723. }
  724. return nullptr;
  725. }
  726. #endif
  727. #ifdef SK_METAL
  728. bool GrBackendRenderTarget::getMtlTextureInfo(GrMtlTextureInfo* outInfo) const {
  729. if (this->isValid() && GrBackendApi::kMetal == fBackend) {
  730. *outInfo = fMtlInfo;
  731. return true;
  732. }
  733. return false;
  734. }
  735. #endif
  736. bool GrBackendRenderTarget::getGLFramebufferInfo(GrGLFramebufferInfo* outInfo) const {
  737. if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
  738. *outInfo = fGLInfo;
  739. return true;
  740. }
  741. return false;
  742. }
  743. GrBackendFormat GrBackendRenderTarget::getBackendFormat() const {
  744. if (!this->isValid()) {
  745. return GrBackendFormat();
  746. }
  747. switch (fBackend) {
  748. #ifdef SK_GL
  749. case GrBackendApi::kOpenGL:
  750. return GrBackendFormat::MakeGL(fGLInfo.fFormat, GR_GL_TEXTURE_NONE);
  751. #endif
  752. #ifdef SK_VULKAN
  753. case GrBackendApi::kVulkan: {
  754. auto info = fVkInfo.snapImageInfo();
  755. if (info.fYcbcrConversionInfo.isValid()) {
  756. SkASSERT(info.fFormat == VK_FORMAT_UNDEFINED);
  757. return GrBackendFormat::MakeVk(info.fYcbcrConversionInfo);
  758. }
  759. return GrBackendFormat::MakeVk(info.fFormat);
  760. }
  761. #endif
  762. #ifdef SK_METAL
  763. case GrBackendApi::kMetal: {
  764. GrMtlTextureInfo mtlInfo;
  765. SkAssertResult(this->getMtlTextureInfo(&mtlInfo));
  766. return GrBackendFormat::MakeMtl(GrGetMTLPixelFormatFromMtlTextureInfo(mtlInfo));
  767. }
  768. #endif
  769. case GrBackendApi::kMock:
  770. return fMockInfo.getBackendFormat();
  771. default:
  772. return GrBackendFormat();
  773. }
  774. }
  775. bool GrBackendRenderTarget::getMockRenderTargetInfo(GrMockRenderTargetInfo* outInfo) const {
  776. if (this->isValid() && GrBackendApi::kMock == fBackend) {
  777. *outInfo = fMockInfo;
  778. return true;
  779. }
  780. return false;
  781. }
  782. bool GrBackendRenderTarget::isProtected() const {
  783. if (!this->isValid() || this->backend() != GrBackendApi::kVulkan) {
  784. return false;
  785. }
  786. return fVkInfo.isProtected();
  787. }
  788. #if GR_TEST_UTILS
  789. bool GrBackendRenderTarget::TestingOnly_Equals(const GrBackendRenderTarget& r0,
  790. const GrBackendRenderTarget& r1) {
  791. if (!r0.isValid() || !r1.isValid()) {
  792. return false; // two invalid backend rendertargets are not considered equal
  793. }
  794. if (r0.fWidth != r1.fWidth ||
  795. r0.fHeight != r1.fHeight ||
  796. r0.fSampleCnt != r1.fSampleCnt ||
  797. r0.fStencilBits != r1.fStencilBits ||
  798. r0.fConfig != r1.fConfig ||
  799. r0.fBackend != r1.fBackend) {
  800. return false;
  801. }
  802. switch (r0.fBackend) {
  803. #ifdef SK_GL
  804. case GrBackendApi::kOpenGL:
  805. return r0.fGLInfo == r1.fGLInfo;
  806. #endif
  807. case GrBackendApi::kMock:
  808. return r0.fMockInfo == r1.fMockInfo;
  809. #ifdef SK_VULKAN
  810. case GrBackendApi::kVulkan:
  811. return r0.fVkInfo == r1.fVkInfo;
  812. #endif
  813. #ifdef SK_METAL
  814. case GrBackendApi::kMetal:
  815. return r0.fMtlInfo == r1.fMtlInfo;
  816. #endif
  817. #ifdef SK_DAWN
  818. case GrBackendApi::kDawn:
  819. return r0.fDawnInfo == r1.fDawnInfo;
  820. #endif
  821. default:
  822. return false;
  823. }
  824. SkASSERT(0);
  825. return false;
  826. }
  827. #endif