blob: b0cc57843ef20157fe48e20951e57dba2d420dc8 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/webgl/webgl_video_texture.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
#include "third_party/blink/renderer/modules/webgl/webgl_video_frame_info.h"
#include "third_party/blink/renderer/modules/webgl/webgl_video_texture_enum.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
WebGLVideoTexture::WebGLVideoTexture(WebGLRenderingContextBase* context)
: WebGLExtension(context) {
context->ExtensionsUtil()->EnsureExtensionEnabled("WEBGL_video_texture");
}
WebGLExtensionName WebGLVideoTexture::GetName() const {
return kWebGLVideoTextureName;
}
WebGLVideoTexture* WebGLVideoTexture::Create(
WebGLRenderingContextBase* context) {
return MakeGarbageCollected<WebGLVideoTexture>(context);
}
// We only need GL_OES_EGL_image_external extension on Android.
bool WebGLVideoTexture::Supported(WebGLRenderingContextBase* context) {
#if defined(OS_ANDROID)
return context->ExtensionsUtil()->SupportsExtension(
"GL_OES_EGL_image_external");
#else // defined OS_ANDROID
return true;
#endif
}
const char* WebGLVideoTexture::ExtensionName() {
return "WEBGL_video_texture";
}
void WebGLVideoTexture::Trace(blink::Visitor* visitor) {
visitor->Trace(current_frame_info_);
WebGLExtension::Trace(visitor);
}
WebGLVideoFrameInfo* WebGLVideoTexture::VideoElementTargetVideoTexture(
ExecutionContext* execution_context,
unsigned target,
HTMLVideoElement* video,
ExceptionState& exceptionState) {
WebGLExtensionScopedContext scoped(this);
if (!video || scoped.IsLost())
return nullptr;
if (target != GL_TEXTURE_VIDEO_IMAGE_WEBGL) {
scoped.Context()->SynthesizeGLError(GL_INVALID_ENUM, "WEBGLVideoTexture",
"invalid texture target");
}
if (!scoped.Context()->ValidateHTMLVideoElement(
execution_context->GetSecurityOrigin(), "WEBGLVideoTexture", video,
exceptionState) ||
!scoped.Context()->ValidateTexFuncDimensions(
"WEBGLVideoTexture", WebGLRenderingContextBase::kTexImage, target, 0,
video->videoWidth(), video->videoHeight(), 1))
return nullptr;
WebGLTexture* texture =
scoped.Context()->ValidateTextureBinding("WEBGLVideoTexture", target);
if (!texture)
return nullptr;
// For WebGL last-uploaded-frame-metadata API.
WebMediaPlayer::VideoFrameUploadMetadata frame_metadata = {};
int already_uploaded_id = HTMLVideoElement::kNoAlreadyUploadedFrame;
WebMediaPlayer::VideoFrameUploadMetadata* frame_metadata_ptr =
&frame_metadata;
if (RuntimeEnabledFeatures::ExtraWebGLVideoTextureMetadataEnabled()) {
already_uploaded_id = texture->GetLastUploadedVideoFrameId();
}
#if defined(OS_ANDROID)
target = GL_TEXTURE_EXTERNAL_OES;
#else // defined OS_ANDROID
target = GL_TEXTURE_2D;
#endif // defined OS_ANDROID
video->PrepareVideoFrameForWebGL(scoped.Context()->ContextGL(), target,
texture->Object(), already_uploaded_id,
frame_metadata_ptr);
if (!frame_metadata_ptr) {
return nullptr;
}
if (frame_metadata_ptr)
current_frame_info_ = WebGLVideoFrameInfo::Create(frame_metadata_ptr);
return current_frame_info_;
}
} // namespace blink