OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ui/gl/gl_image.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/memory/ref_counted_memory.h" | |
10 #include "base/memory/shared_memory.h" | |
11 #include "base/strings/stringprintf.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "third_party/skia/include/core/SkCanvas.h" | |
14 #include "third_party/skia/include/core/SkColor.h" | |
15 #include "third_party/skia/include/core/SkSurface.h" | |
16 #include "ui/gfx/buffer_format_util.h" | |
17 #include "ui/gfx/buffer_types.h" | |
18 #include "ui/gl/gl_bindings.h" | |
19 #include "ui/gl/gl_context.h" | |
20 #include "ui/gl/gl_image_ref_counted_memory.h" | |
21 #include "ui/gl/gl_image_shared_memory.h" | |
22 #include "ui/gl/gl_implementation.h" | |
23 #include "ui/gl/gl_surface.h" | |
24 #include "ui/gl/gl_version_info.h" | |
25 #include "ui/gl/scoped_make_current.h" | |
26 #include "ui/gl/test/gl_surface_test_support.h" | |
27 | |
28 #if defined(OS_MACOSX) | |
29 #include <CoreFoundation/CoreFoundation.h> | |
30 #include "ui/gl/gl_image_io_surface.h" | |
31 #endif | |
32 | |
33 #if defined(OS_ANDROID) | |
34 #include <android/native_window_jni.h> | |
35 #include "base/android/jni_android.h" | |
36 #include "ui/gl/android/scoped_java_surface.h" | |
37 #include "ui/gl/android/surface_texture.h" | |
38 #include "ui/gl/gl_image_surface_texture.h" | |
39 #endif | |
40 | |
41 namespace gfx { | |
42 namespace { | |
43 | |
44 enum class GLImageType { | |
Daniele Castagna
2015/09/22 15:55:32
Have you considered having one test fixture for ea
reveman
2015/09/24 00:31:42
Latest patch implements this using a test template
| |
45 SHARED_MEMORY, | |
46 REF_COUNTED_MEMORY, | |
47 IO_SURFACE, | |
48 SURFACE_TEXTURE, | |
49 OZONE_NATIVE_PIXMAP | |
50 }; | |
51 | |
52 #define SHADER(Src) #Src | |
53 | |
54 // clang-format off | |
55 | |
56 const char kVertexShader[] = SHADER( | |
57 uniform vec2 texScale; | |
58 attribute vec2 a_position; | |
59 attribute vec2 a_texCoord; | |
60 varying vec2 v_texCoord; | |
61 void main() { | |
62 gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); | |
63 v_texCoord = vec2(a_texCoord.x * texScale.x, a_texCoord.y * texScale.y); | |
64 } | |
65 ); | |
66 | |
67 const char kFragmentShader[] = SHADER( | |
68 uniform SamplerType a_texture; | |
69 varying vec2 v_texCoord; | |
70 void main() { | |
71 gl_FragColor = TextureLookup(a_texture, v_texCoord); | |
72 } | |
73 ); | |
74 | |
75 // clang-format on | |
76 | |
77 const char kTexture2DFragmentShaderPrefix[] = | |
78 "#define SamplerType sampler2D\n" | |
79 "#define TextureLookup texture2D\n"; | |
80 | |
81 const char kTextureRectangleFragmentShaderPrefix[] = | |
82 "#extension GL_ARB_texture_rectangle : require\n" | |
83 "#define SamplerType sampler2DRect\n" | |
84 "#define TextureLookup texture2DRect\n"; | |
85 | |
86 const char kTextureExternalFragmentShaderPrefix[] = | |
87 "#extension GL_OES_EGL_image_external : require\n" | |
88 "#define SamplerType samplerExternalOES\n" | |
89 "#define TextureLookup texture2D\n"; | |
90 | |
91 GLuint LoadShader(GLenum type, const char* const src) { | |
92 GLuint shader = glCreateShader(type); | |
93 glShaderSource(shader, 1, &src, nullptr); | |
94 glCompileShader(shader); | |
95 GLint compiled = 0; | |
96 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); | |
97 DCHECK(compiled); | |
98 return shader; | |
99 } | |
100 | |
101 class GLImageTest : public testing::TestWithParam<GLImageType> { | |
102 public: | |
103 // Overridden from testing::Test: | |
104 void SetUp() override { | |
105 #if defined(USE_OZONE) | |
106 // On Ozone, the backend initializes the event system using a UI thread. | |
107 base::MessageLoopForUI main_loop; | |
108 #endif | |
109 | |
110 std::vector<GLImplementation> allowed_impls; | |
111 GetAllowedGLImplementations(&allowed_impls); | |
112 DCHECK(!allowed_impls.empty()); | |
113 | |
114 GLImplementation impl = allowed_impls[0]; | |
115 GLSurfaceTestSupport::InitializeOneOffImplementation(impl); | |
116 | |
117 surface_ = GLSurface::CreateOffscreenGLSurface(Size()); | |
118 context_ = GLContext::CreateGLContext(nullptr, surface_.get(), | |
119 PreferIntegratedGpu); | |
120 | |
121 ui::ScopedMakeCurrent scoped_make_current(context_.get(), surface_.get()); | |
122 | |
123 bool has_texture_format_bgra8888 = | |
124 context_->HasExtension("GL_APPLE_texture_format_BGRA8888") || | |
125 context_->HasExtension("GL_EXT_texture_format_BGRA8888") || | |
126 !context_->GetVersionInfo()->is_es; | |
127 if (!SK_B32_SHIFT && has_texture_format_bgra8888) { | |
128 preferred_format_ = BufferFormat::BGRA_8888; | |
129 preferred_internal_format_ = GL_BGRA_EXT; | |
130 } | |
131 | |
132 glGenTextures(1, &color_texture_); | |
133 glBindTexture(GL_TEXTURE_2D, color_texture_); | |
134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
135 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
138 // Create a 1024x1024 color buffer. | |
139 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, | |
140 GL_UNSIGNED_BYTE, nullptr); | |
141 glBindTexture(GL_TEXTURE_2D, 0); | |
142 glGenFramebuffersEXT(1, &framebuffer_); | |
143 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_); | |
144 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
145 GL_TEXTURE_2D, color_texture_, 0); | |
146 DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), | |
147 glCheckFramebufferStatusEXT(GL_FRAMEBUFFER)); | |
148 | |
149 vertex_shader_ = LoadShader(GL_VERTEX_SHADER, kVertexShader); | |
150 bool is_gles = context_->GetVersionInfo()->is_es; | |
151 fragment_shader_ = | |
152 LoadShader(GL_FRAGMENT_SHADER, | |
153 base::StringPrintf("%s%s%s", TextureFragmentShaderPrefix(), | |
154 is_gles ? "precision mediump float;" : "", | |
155 kFragmentShader) | |
156 .c_str()); | |
157 program_ = glCreateProgram(); | |
158 glAttachShader(program_, vertex_shader_); | |
159 glAttachShader(program_, fragment_shader_); | |
160 glBindAttribLocation(program_, 0, "a_position"); | |
161 glBindAttribLocation(program_, 1, "a_texCoord"); | |
162 glLinkProgram(program_); | |
163 GLint linked = -1; | |
164 glGetProgramiv(program_, GL_LINK_STATUS, &linked); | |
165 DCHECK_NE(linked, 0); | |
166 glUseProgram(program_); | |
167 sampler_location_ = glGetUniformLocation(program_, "a_texture"); | |
168 DCHECK_NE(sampler_location_, -1); | |
169 glUniform1i(sampler_location_, 0); | |
170 texture_scale_location_ = glGetUniformLocation(program_, "texScale"); | |
171 DCHECK_NE(texture_scale_location_, -1); | |
172 glUniform2f(texture_scale_location_, 1.f, 1.0f); | |
173 | |
174 glGenBuffersARB(1, &vertex_buffer_); | |
175 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | |
176 // clang-format off | |
177 static GLfloat vertices[] = { | |
178 -1.f, -1.f, 0.f, 0.f, | |
179 1.f, -1.f, 1.f, 0.f, | |
180 -1.f, 1.f, 0.f, 1.f, | |
181 1.f, 1.f, 1.f, 1.f | |
182 }; | |
183 // clang-format on | |
184 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | |
185 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0); | |
186 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, | |
187 reinterpret_cast<void*>(sizeof(GLfloat) * 2)); | |
188 glEnableVertexAttribArray(0); | |
189 glEnableVertexAttribArray(1); | |
190 } | |
191 void TearDown() override { | |
192 { | |
193 ui::ScopedMakeCurrent scoped_make_current(context_.get(), surface_.get()); | |
194 | |
195 glDeleteProgram(program_); | |
196 glDeleteShader(vertex_shader_); | |
197 glDeleteShader(fragment_shader_); | |
198 glBindBuffer(GL_ARRAY_BUFFER, 0); | |
199 glDeleteBuffersARB(1, &vertex_buffer_); | |
200 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | |
201 glDeleteFramebuffersEXT(1, &framebuffer_); | |
202 glDeleteTextures(1, &color_texture_); | |
203 } | |
204 | |
205 context_ = nullptr; | |
206 surface_ = nullptr; | |
207 | |
208 ClearGLBindings(); | |
209 } | |
210 | |
211 protected: | |
212 scoped_refptr<GLImage> CreateSolidColorImage(const Size& size, | |
213 unsigned internalformat, | |
214 BufferFormat format, | |
215 SkColor color) { | |
216 switch (GetParam()) { | |
217 case GLImageType::SHARED_MEMORY: { | |
218 DCHECK_EQ(NumberOfPlanesForBufferFormat(format), 1u); | |
219 base::SharedMemory shared_memory; | |
220 if (!shared_memory.CreateAndMapAnonymous( | |
221 BufferSizeForBufferFormat(size, format))) { | |
222 return nullptr; | |
223 } | |
224 ClearDataToSolidColor( | |
225 size, format, | |
226 static_cast<int>(RowSizeForBufferFormat(size.width(), format, 0)), | |
227 reinterpret_cast<uint8_t*>(shared_memory.memory()), color); | |
228 | |
229 scoped_refptr<GLImageSharedMemory> image( | |
230 new GLImageSharedMemory(size, internalformat)); | |
231 if (!image->Initialize( | |
232 base::SharedMemory::DuplicateHandle(shared_memory.handle()), | |
233 NextGenericSharedMemoryId(), format)) { | |
234 return nullptr; | |
235 } | |
236 return image; | |
237 } | |
238 case GLImageType::REF_COUNTED_MEMORY: { | |
239 DCHECK_EQ(NumberOfPlanesForBufferFormat(format), 1u); | |
240 std::vector<uint8_t> data(BufferSizeForBufferFormat(size, format), 0); | |
241 scoped_refptr<base::RefCountedBytes> bytes( | |
242 new base::RefCountedBytes(data)); | |
243 ClearDataToSolidColor( | |
244 size, format, | |
245 static_cast<int>(RowSizeForBufferFormat(size.width(), format, 0)), | |
246 &bytes->data().front(), color); | |
247 | |
248 scoped_refptr<GLImageRefCountedMemory> image( | |
249 new GLImageRefCountedMemory(size, internalformat)); | |
250 if (!image->Initialize(bytes.get(), format)) | |
251 return nullptr; | |
252 return image; | |
253 } | |
254 case GLImageType::IO_SURFACE: { | |
255 #if defined(OS_MACOSX) | |
256 DCHECK(format == BufferFormat::BGRA_8888); | |
257 base::ScopedCFTypeRef<CFMutableDictionaryRef> properties( | |
258 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | |
259 &kCFTypeDictionaryKeyCallBacks, | |
260 &kCFTypeDictionaryValueCallBacks)); | |
261 int32_t width = size.width(); | |
262 base::ScopedCFTypeRef<CFNumberRef> cf_width( | |
263 CFNumberCreate(nullptr, kCFNumberSInt32Type, &width)); | |
264 CFDictionaryAddValue(properties, kIOSurfaceWidth, cf_width.get()); | |
265 int32_t height = size.height(); | |
266 base::ScopedCFTypeRef<CFNumberRef> cf_height( | |
267 CFNumberCreate(nullptr, kCFNumberSInt32Type, &height)); | |
268 CFDictionaryAddValue(properties, kIOSurfaceHeight, cf_height.get()); | |
269 int32_t pixel_format = 'BGRA'; | |
270 base::ScopedCFTypeRef<CFNumberRef> cf_pixel_format( | |
271 CFNumberCreate(nullptr, kCFNumberSInt32Type, &pixel_format)); | |
272 CFDictionaryAddValue(properties, kIOSurfacePixelFormat, | |
273 cf_pixel_format.get()); | |
274 int32_t bytes_per_element = 4; | |
275 base::ScopedCFTypeRef<CFNumberRef> cf_bytes_per_element( | |
276 CFNumberCreate(nullptr, kCFNumberSInt32Type, &bytes_per_element)); | |
277 CFDictionaryAddValue(properties, kIOSurfaceBytesPerElement, | |
278 cf_bytes_per_element.get()); | |
279 base::ScopedCFTypeRef<IOSurfaceRef> io_surface( | |
280 IOSurfaceCreate(properties)); | |
281 DCHECK(io_surface); | |
282 IOReturn status = IOSurfaceLock(io_surface, 0, nullptr); | |
283 DCHECK_EQ(status, kIOReturnSuccess); | |
284 ClearDataToSolidColor( | |
285 size, format, static_cast<int>(IOSurfaceGetBytesPerRow(io_surface)), | |
286 reinterpret_cast<uint8_t*>(IOSurfaceGetBaseAddress(io_surface)), | |
287 color); | |
288 IOSurfaceUnlock(io_surface, 0, nullptr); | |
289 | |
290 scoped_refptr<GLImageIOSurface> image( | |
291 new GLImageIOSurface(size, internalformat)); | |
292 if (!image->Initialize(io_surface, NextGenericSharedMemoryId(), | |
293 format)) { | |
294 return nullptr; | |
295 } | |
296 return image; | |
297 #else | |
298 NOTREACHED(); | |
299 return nullptr; | |
300 #endif | |
301 } | |
302 case GLImageType::SURFACE_TEXTURE: { | |
303 #if defined(OS_ANDROID) | |
304 const int kDummyTextureId = 0; | |
305 scoped_refptr<SurfaceTexture> surface_texture = | |
306 SurfaceTexture::Create(kDummyTextureId); | |
307 DCHECK(surface_texture); | |
308 DCHECK(format == BufferFormat::RGBA_8888); | |
309 ScopedJavaSurface surface(surface_texture.get()); | |
310 JNIEnv* env = base::android::AttachCurrentThread(); | |
311 ANativeWindow* native_window = | |
312 ANativeWindow_fromSurface(env, surface.j_surface().obj()); | |
313 ANativeWindow_setBuffersGeometry(native_window, size.width(), | |
314 size.height(), | |
315 WINDOW_FORMAT_RGBA_8888); | |
316 ANativeWindow_Buffer buffer; | |
317 int rv = ANativeWindow_lock(native_window, &buffer, nullptr); | |
318 DCHECK_EQ(rv, 0); | |
319 ClearDataToSolidColor(size, format, buffer.stride, | |
320 reinterpret_cast<uint8_t*>(buffer.bits), color); | |
321 ANativeWindow_unlockAndPost(native_window); | |
322 | |
323 scoped_refptr<GLImageSurfaceTexture> image( | |
324 new GLImageSurfaceTexture(size)); | |
325 if (!image->Initialize(surface_texture.get())) | |
326 return nullptr; | |
327 return image; | |
328 #else | |
329 NOTREACHED(); | |
330 return nullptr; | |
331 #endif | |
332 } | |
333 case GLImageType::OZONE_NATIVE_PIXMAP: | |
334 NOTREACHED(); | |
335 return nullptr; | |
336 } | |
337 NOTREACHED(); | |
338 return nullptr; | |
339 } | |
340 | |
341 GLenum GetTextureTarget() { | |
342 switch (GetParam()) { | |
343 case GLImageType::SHARED_MEMORY: | |
344 case GLImageType::REF_COUNTED_MEMORY: | |
345 return GL_TEXTURE_2D; | |
346 case GLImageType::IO_SURFACE: | |
347 return GL_TEXTURE_RECTANGLE_ARB; | |
348 case GLImageType::SURFACE_TEXTURE: | |
349 case GLImageType::OZONE_NATIVE_PIXMAP: | |
350 return GL_TEXTURE_EXTERNAL_OES; | |
351 } | |
352 NOTREACHED(); | |
353 return GL_TEXTURE_2D; | |
354 } | |
355 | |
356 const char* TextureFragmentShaderPrefix() { | |
357 switch (GetParam()) { | |
358 case GLImageType::SHARED_MEMORY: | |
359 case GLImageType::REF_COUNTED_MEMORY: | |
360 return kTexture2DFragmentShaderPrefix; | |
361 case GLImageType::IO_SURFACE: | |
362 return kTextureRectangleFragmentShaderPrefix; | |
363 case GLImageType::SURFACE_TEXTURE: | |
364 case GLImageType::OZONE_NATIVE_PIXMAP: | |
365 return kTextureExternalFragmentShaderPrefix; | |
366 } | |
367 NOTREACHED(); | |
368 return nullptr; | |
369 } | |
370 | |
371 Vector2dF GetTextureScale(Size size) { | |
372 switch (GetParam()) { | |
373 case GLImageType::SHARED_MEMORY: | |
374 case GLImageType::REF_COUNTED_MEMORY: | |
375 case GLImageType::SURFACE_TEXTURE: | |
376 case GLImageType::OZONE_NATIVE_PIXMAP: | |
377 return Vector2dF(1.f, 1.f); | |
378 case GLImageType::IO_SURFACE: | |
379 return Vector2dF(size.width(), size.height()); | |
380 } | |
381 NOTREACHED(); | |
382 return Vector2dF(); | |
383 } | |
384 | |
385 void DrawTexture(Size size) { | |
386 Vector2dF texture_scale = GetTextureScale(size); | |
387 glUniform2f(texture_scale_location_, texture_scale.x(), texture_scale.y()); | |
388 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
389 } | |
390 | |
391 GenericSharedMemoryId NextGenericSharedMemoryId() { | |
392 return GenericSharedMemoryId(next_generic_shared_memory_id_++); | |
393 } | |
394 | |
395 bool CheckPixels(int x, int y, int width, int height, SkColor color) { | |
396 int size = width * height * 4; | |
397 scoped_ptr<uint8_t[]> pixels(new uint8_t[size]); | |
398 const uint8_t kCheckClearValue = 123u; | |
399 memset(pixels.get(), kCheckClearValue, size); | |
400 glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); | |
401 uint8_t expected_color[] = { | |
402 SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), | |
403 SkColorGetA(color), | |
404 }; | |
405 int bad_count = 0; | |
406 for (int yy = 0; yy < height; ++yy) { | |
407 for (int xx = 0; xx < width; ++xx) { | |
408 int offset = yy * width * 4 + xx * 4; | |
409 for (int jj = 0; jj < 4; ++jj) { | |
410 uint8_t actual = pixels[offset + jj]; | |
411 uint8_t expected = expected_color[jj]; | |
412 EXPECT_EQ(expected, actual) << " at " << (xx + x) << ", " << (yy + y) | |
413 << " channel " << jj; | |
414 bad_count += actual != expected; | |
415 // Exit early just so we don't spam the log but we print enough to | |
416 // hopefully make it easy to diagnose the issue. | |
417 if (bad_count > 16) | |
418 return false; | |
419 } | |
420 } | |
421 } | |
422 | |
423 return !bad_count; | |
424 } | |
425 | |
426 void ClearDataToSolidColor(const Size& size, | |
427 BufferFormat format, | |
428 int stride, | |
429 uint8_t* data, | |
430 SkColor color) { | |
431 switch (format) { | |
432 case BufferFormat::RGBA_8888: | |
433 for (int y = 0; y < size.height(); ++y) { | |
434 for (int x = 0; x < size.width(); ++x) { | |
435 data[y * stride + x * 4 + 0] = SkColorGetR(color); | |
436 data[y * stride + x * 4 + 1] = SkColorGetG(color); | |
437 data[y * stride + x * 4 + 2] = SkColorGetB(color); | |
438 data[y * stride + x * 4 + 3] = SkColorGetA(color); | |
439 } | |
440 } | |
441 return; | |
442 case BufferFormat::BGRA_8888: | |
443 for (int y = 0; y < size.height(); ++y) { | |
444 for (int x = 0; x < size.width(); ++x) { | |
445 data[y * stride + x * 4 + 0] = SkColorGetB(color); | |
446 data[y * stride + x * 4 + 1] = SkColorGetG(color); | |
447 data[y * stride + x * 4 + 2] = SkColorGetR(color); | |
448 data[y * stride + x * 4 + 3] = SkColorGetA(color); | |
449 } | |
450 } | |
451 return; | |
452 case BufferFormat::ATC: | |
453 case BufferFormat::ATCIA: | |
454 case BufferFormat::DXT1: | |
455 case BufferFormat::DXT5: | |
456 case BufferFormat::ETC1: | |
457 case BufferFormat::R_8: | |
458 case BufferFormat::RGBA_4444: | |
459 case BufferFormat::BGRX_8888: | |
460 case BufferFormat::UYVY_422: | |
461 case BufferFormat::YUV_420_BIPLANAR: | |
462 case BufferFormat::YUV_420: | |
463 NOTREACHED(); | |
464 return; | |
465 } | |
466 NOTREACHED(); | |
467 } | |
468 | |
469 scoped_refptr<GLContext> context_; | |
470 scoped_refptr<GLSurface> surface_; | |
471 BufferFormat preferred_format_ = BufferFormat::RGBA_8888; | |
472 GLenum preferred_internal_format_ = GL_RGBA; | |
473 GLuint color_texture_ = 0; | |
474 GLuint framebuffer_ = 0; | |
475 GLuint vertex_shader_ = 0; | |
476 GLuint fragment_shader_ = 0; | |
477 GLuint program_ = 0; | |
478 GLuint vertex_buffer_ = 0; | |
479 GLint sampler_location_ = -1; | |
480 GLint texture_scale_location_ = -1; | |
481 int next_generic_shared_memory_id_ = 1; | |
482 }; | |
483 | |
484 TEST_P(GLImageTest, CopyTexSubImage) { | |
Daniele Castagna
2015/09/22 15:55:32
Can you spend few words here describing CopyTexSub
reveman
2015/09/24 00:31:42
Added some more comments to latest patch but I'd r
| |
485 ui::ScopedMakeCurrent scoped_make_current(context_.get(), surface_.get()); | |
486 | |
487 const Size image_size(256, 256); | |
488 scoped_refptr<GLImage> image = CreateSolidColorImage( | |
489 image_size, preferred_internal_format_, preferred_format_, SK_ColorGREEN); | |
490 if (!image) | |
Daniele Castagna
2015/09/22 15:55:32
When would this happen?
reveman
2015/09/24 00:31:42
Made it a requirement for this to be supported by
| |
491 return; | |
492 | |
493 GLenum target = GetTextureTarget(); | |
494 GLuint texture = 0; | |
495 glGenTextures(1, &texture); | |
496 glBindTexture(target, texture); | |
497 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
498 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
499 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
500 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
501 glTexImage2D(target, 0, preferred_internal_format_, image_size.width(), | |
502 image_size.height(), 0, preferred_internal_format_, | |
503 GL_UNSIGNED_BYTE, nullptr); | |
504 | |
505 // Copy image to |texture|. If supported, check that |texture| contains | |
506 // the correct result. | |
507 if (image->CopyTexSubImage(target, Point(), Rect(image_size))) { | |
Daniele Castagna
2015/09/22 15:55:32
Is it OK not to support CopyTexSubImage?
If that i
reveman
2015/09/24 00:31:42
Yes.
| |
508 glViewport(0, 0, image_size.width(), image_size.height()); | |
509 DrawTexture(image_size); | |
510 CheckPixels(0, 0, image_size.width(), image_size.height(), SK_ColorGREEN); | |
511 } | |
512 | |
513 glDeleteTextures(1, &texture); | |
514 image->Destroy(true); | |
515 } | |
516 | |
517 static const GLImageType kGLImageTypes[] = { | |
518 GLImageType::SHARED_MEMORY, GLImageType::REF_COUNTED_MEMORY, | |
519 #if defined(OS_MACOSX) | |
520 GLImageType::IO_SURFACE, | |
521 #endif | |
522 #if defined(OS_ANDROID) | |
523 GLImageType::SURFACE_TEXTURE, | |
524 #endif | |
525 }; | |
526 | |
527 INSTANTIATE_TEST_CASE_P(GLImageTests, | |
528 GLImageTest, | |
529 ::testing::ValuesIn(kGLImageTypes)); | |
530 | |
531 } // namespace | |
532 } // namespace gfx | |
OLD | NEW |