OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 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 | |
8 #include "Test.h" | |
9 #if SK_SUPPORT_GPU | |
10 #include "GrContext.h" | |
11 #include "GrContextFactory.h" | |
12 #include "gl/GrGLGpu.h" | |
13 #include "gl/GrGLUtil.h" | |
14 #include "gl/SkGLContext.h" | |
15 | |
16 static void cleanup(SkGLContext* glctx0, GrGLuint texID0, SkGLContext* glctx1, G
rContext* grctx1, | |
17 const GrGLTextureInfo* grbackendtex1, GrEGLImage image1) { | |
18 if (glctx1) { | |
19 glctx1->makeCurrent(); | |
20 if (grctx1) { | |
21 if (grbackendtex1) { | |
22 GrGLGpu* gpu1 = static_cast<GrGLGpu*>(grctx1->getGpu()); | |
23 GrBackendObject handle = reinterpret_cast<GrBackendObject>(grbac
kendtex1); | |
24 gpu1->deleteTestingOnlyBackendTexture(handle, false); | |
25 } | |
26 grctx1->unref(); | |
27 } | |
28 if (GR_EGL_NO_IMAGE != image1) { | |
29 glctx1->destroyEGLImage(image1); | |
30 } | |
31 glctx1->unref(); | |
32 } | |
33 | |
34 glctx0->makeCurrent(); | |
35 if (texID0) { | |
36 GR_GL_CALL(glctx0->gl(), DeleteTextures(1, &texID0)); | |
37 } | |
38 } | |
39 | |
40 DEF_GPUTEST(EGLImageTest, reporter, factory) { | |
41 for (int glCtxType = 0; glCtxType < GrContextFactory::kGLContextTypeCnt; ++g
lCtxType) { | |
42 GrContextFactory::GLContextType type = (GrContextFactory::GLContextType)
glCtxType; | |
43 if (!GrContextFactory::IsRenderingGLContext(type)) { | |
44 continue; | |
45 } | |
46 | |
47 // Try to create a second GL context and then check if the contexts have
necessary | |
48 // extensions to run this test. | |
49 | |
50 GrContext* context0 = factory->get(type); | |
51 if (!context0) { | |
52 continue; | |
53 } | |
54 SkGLContext* glCtx0 = factory->getGLContext(type); | |
55 SkGLContext* glCtx1 = glCtx0->createNew(); | |
56 if (!glCtx1) { | |
57 continue; | |
58 } | |
59 GrContext* context1 = GrContext::Create(kOpenGL_GrBackend, (GrBackendCon
text)glCtx1->gl()); | |
60 const GrGLTextureInfo* backendTexture1 = nullptr; | |
61 GrEGLImage image = GR_EGL_NO_IMAGE; | |
62 GrGLTextureInfo externalTexture; | |
63 externalTexture.fID = 0; | |
64 | |
65 if (!context1) { | |
66 cleanup(glCtx0, externalTexture.fID, glCtx1, context1, backendTextur
e1, image); | |
67 continue; | |
68 } | |
69 | |
70 SkASSERT(glCtx0); | |
71 if (!glCtx0->gl()->hasExtension("EGL_KHR_image") || | |
72 !glCtx0->gl()->hasExtension("GL_OES_EGL_image_external") || | |
73 !glCtx1->gl()->hasExtension("EGL_KHR_image") || | |
74 !glCtx1->gl()->hasExtension("EGL_KHR_gl_texture_2D_image")) { | |
75 cleanup(glCtx0, externalTexture.fID, glCtx1, context1, backendTextur
e1, image); | |
76 continue; | |
77 } | |
78 | |
79 ///////////////////////////////// CONTEXT 1 /////////////////////////////////// | |
80 | |
81 // Use GL Context 1 to create a texture unknown to GrContext. | |
82 context1->flush(); | |
83 GrGpu* gpu1 = context1->getGpu(); | |
84 static const int kSize = 100; | |
85 backendTexture1 = reinterpret_cast<const GrGLTextureInfo*>( | |
86 gpu1->createTestingOnlyBackendTexture(nullptr, kSize, kSize, kRGBA_8
888_GrPixelConfig)); | |
87 if (!backendTexture1 || !backendTexture1->fID) { | |
88 ERRORF(reporter, "Error creating texture for EGL Image"); | |
89 cleanup(glCtx0, externalTexture.fID, glCtx1, context1, backendTextur
e1, image); | |
90 continue; | |
91 } | |
92 if (GR_GL_TEXTURE_2D != backendTexture1->fTarget) { | |
93 ERRORF(reporter, "Expected backend texture to be 2D"); | |
94 cleanup(glCtx0, externalTexture.fID, glCtx1, context1, backendTextur
e1, image); | |
95 continue; | |
96 } | |
97 | |
98 // Wrap the texture in an EGLImage | |
99 image = glCtx1->texture2DToEGLImage(backendTexture1->fID); | |
100 if (GR_EGL_NO_IMAGE == image) { | |
101 ERRORF(reporter, "Error creating EGL Image from texture"); | |
102 cleanup(glCtx0, externalTexture.fID, glCtx1, context1, backendTextur
e1, image); | |
103 continue; | |
104 } | |
105 | |
106 // Populate the texture using GL context 1. Important to use TexSubImage
as TexImage orphans | |
107 // the EGL image. Also, this must be done after creating the EGLImage as
the texture | |
108 // contents may not be preserved when the image is created. | |
109 SkAutoTMalloc<uint32_t> pixels(kSize * kSize); | |
110 for (int i = 0; i < kSize*kSize; ++i) { | |
111 pixels.get()[i] = 0xDDAABBCC; | |
112 } | |
113 GR_GL_CALL(glCtx1->gl(), ActiveTexture(GR_GL_TEXTURE0)); | |
114 GR_GL_CALL(glCtx1->gl(), BindTexture(backendTexture1->fTarget, backendTe
xture1->fID)); | |
115 GR_GL_CALL(glCtx1->gl(), TexSubImage2D(backendTexture1->fTarget, 0, 0, 0
, kSize, kSize, | |
116 GR_GL_RGBA, GR_GL_UNSIGNED_BYTE,
pixels.get())); | |
117 GR_GL_CALL(glCtx1->gl(), Finish()); | |
118 // We've been making direct GL calls in GL context 1, let GrContext 1 kn
ow its internal | |
119 // state is invalid. | |
120 context1->resetContext(); | |
121 | |
122 ///////////////////////////////// CONTEXT 0 /////////////////////////////////// | |
123 | |
124 // Make a new texture ID in GL Context 0 from the EGL Image | |
125 glCtx0->makeCurrent(); | |
126 externalTexture.fTarget = GR_GL_TEXTURE_EXTERNAL; | |
127 externalTexture.fID = glCtx0->eglImageToExternalTexture(image); | |
128 | |
129 // Wrap this texture ID in a GrTexture | |
130 GrBackendTextureDesc externalDesc; | |
131 externalDesc.fConfig = kRGBA_8888_GrPixelConfig; | |
132 externalDesc.fWidth = kSize; | |
133 externalDesc.fHeight = kSize; | |
134 externalDesc.fTextureHandle = reinterpret_cast<GrBackendObject>(&externa
lTexture); | |
135 SkAutoTUnref<GrTexture> externalTextureObj( | |
136 context0->textureProvider()->wrapBackendTexture(externalDesc)); | |
137 if (!externalTextureObj) { | |
138 ERRORF(reporter, "Error wrapping external texture in GrTexture."); | |
139 cleanup(glCtx0, externalTexture.fID, glCtx1, context1, backendTextur
e1, image); | |
140 continue; | |
141 } | |
142 | |
143 // Read the pixels and see if we get the values set in GL context 1 | |
144 memset(pixels.get(), 0, sizeof(uint32_t)*kSize*kSize); | |
145 bool read = externalTextureObj->readPixels(0, 0, kSize, kSize, kRGBA_888
8_GrPixelConfig, | |
146 pixels.get()); | |
147 if (!read) { | |
148 ERRORF(reporter, "Error reading external texture."); | |
149 cleanup(glCtx0, externalTexture.fID, glCtx1, context1, backendTextur
e1, image); | |
150 continue; | |
151 } | |
152 for (int i = 0; i < kSize*kSize; ++i) { | |
153 if (pixels.get()[i] != 0xDDAABBCC) { | |
154 ERRORF(reporter, "Error, external texture pixel value %d should
be 0xDDAABBCC," | |
155 " got 0x%08x.", pixels.get()[i]); | |
156 break; | |
157 } | |
158 } | |
159 cleanup(glCtx0, externalTexture.fID, glCtx1, context1, backendTexture1,
image); | |
160 } | |
161 } | |
162 | |
163 #endif | |
OLD | NEW |