Fix race condition in gyp/ninja builds.
[chromium-blink-merge.git] / ui / gl / gl_image_android_native_buffer.cc
blob6d11497b2a31ccd36bef9b7231917b194b89438d
1 // Copyright 2014 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.
5 #include "ui/gl/gl_image_android_native_buffer.h"
7 #include "ui/gl/gl_surface_egl.h"
8 #include "ui/gl/scoped_binders.h"
10 namespace gfx {
12 GLImageAndroidNativeBuffer::GLImageAndroidNativeBuffer(gfx::Size size)
13 : GLImageEGL(size),
14 release_after_use_(false),
15 in_use_(false),
16 target_(0),
17 egl_image_for_unbind_(EGL_NO_IMAGE_KHR),
18 texture_id_for_unbind_(0) {}
20 GLImageAndroidNativeBuffer::~GLImageAndroidNativeBuffer() { Destroy(); }
22 bool GLImageAndroidNativeBuffer::Initialize(gfx::GpuMemoryBufferHandle buffer) {
23 DCHECK(buffer.native_buffer);
25 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
26 return GLImageEGL::Initialize(
27 EGL_NATIVE_BUFFER_ANDROID, buffer.native_buffer, attrs);
30 void GLImageAndroidNativeBuffer::Destroy() {
31 if (egl_image_for_unbind_ != EGL_NO_IMAGE_KHR) {
32 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
33 egl_image_for_unbind_);
34 egl_image_for_unbind_ = EGL_NO_IMAGE_KHR;
36 if (texture_id_for_unbind_) {
37 glDeleteTextures(1, &texture_id_for_unbind_);
38 texture_id_for_unbind_ = 0;
41 GLImageEGL::Destroy();
44 bool GLImageAndroidNativeBuffer::BindTexImage(unsigned target) {
45 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_);
47 if (target == GL_TEXTURE_RECTANGLE_ARB) {
48 LOG(ERROR) << "EGLImage cannot be bound to TEXTURE_RECTANGLE_ARB target";
49 return false;
52 if (target_ && target_ != target) {
53 LOG(ERROR) << "EGLImage can only be bound to one target";
54 return false;
56 target_ = target;
58 // Defer ImageTargetTexture2D if not currently in use.
59 if (!in_use_)
60 return true;
62 glEGLImageTargetTexture2DOES(target_, egl_image_);
63 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
64 return true;
67 void GLImageAndroidNativeBuffer::WillUseTexImage() {
68 DCHECK(egl_image_);
69 DCHECK(!in_use_);
70 in_use_ = true;
71 glEGLImageTargetTexture2DOES(target_, egl_image_);
72 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
75 void GLImageAndroidNativeBuffer::DidUseTexImage() {
76 DCHECK(in_use_);
77 in_use_ = false;
79 if (!release_after_use_)
80 return;
82 if (egl_image_for_unbind_ == EGL_NO_IMAGE_KHR) {
83 DCHECK_EQ(0u, texture_id_for_unbind_);
84 glGenTextures(1, &texture_id_for_unbind_);
87 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_for_unbind_);
88 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
89 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
90 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
92 char zero[4] = {0, };
93 glTexImage2D(
94 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &zero);
97 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
98 // Need to pass current EGL rendering context to eglCreateImageKHR for
99 // target type EGL_GL_TEXTURE_2D_KHR.
100 egl_image_for_unbind_ = eglCreateImageKHR(
101 GLSurfaceEGL::GetHardwareDisplay(),
102 eglGetCurrentContext(),
103 EGL_GL_TEXTURE_2D_KHR,
104 reinterpret_cast<EGLClientBuffer>(texture_id_for_unbind_),
105 attrs);
106 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_for_unbind_)
107 << "Error creating EGLImage: " << eglGetError();
110 glEGLImageTargetTexture2DOES(target_, egl_image_for_unbind_);
111 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
114 void GLImageAndroidNativeBuffer::SetReleaseAfterUse() {
115 release_after_use_ = true;
118 } // namespace gfx