summaryrefslogtreecommitdiffstats
path: root/ppapi/examples
diff options
context:
space:
mode:
authorsail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-08 22:14:11 +0000
committersail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-08 22:14:11 +0000
commit2ab83919c9c98330f453052130176a8320779ed3 (patch)
tree20fd0ff34df907bc400753f00acf36e378094946 /ppapi/examples
parenteb40bef833f9ccbfb73075d8fd0791f5f1f094fe (diff)
downloadchromium_src-2ab83919c9c98330f453052130176a8320779ed3.zip
chromium_src-2ab83919c9c98330f453052130176a8320779ed3.tar.gz
chromium_src-2ab83919c9c98330f453052130176a8320779ed3.tar.bz2
hook up new MacVideoDecodeAccelerator
This CL hooks up the new MacVideoDecodeAccelerator so that it can be instantiated by the HTML5 and pepper code. Currently only the pepper code uses it. I also updated the pepper video_decode example app to be able to draw the GL_TEXTURE_RECTANGLE_ARB textures that the Mac decoder generates. BUG=127414 TEST= Review URL: https://chromiumcodereview.appspot.com/10411042 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141302 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/examples')
-rw-r--r--ppapi/examples/video_decode/video_decode.cc172
1 files changed, 125 insertions, 47 deletions
diff --git a/ppapi/examples/video_decode/video_decode.cc b/ppapi/examples/video_decode/video_decode.cc
index 6e4f4e1..4e3354a 100644
--- a/ppapi/examples/video_decode/video_decode.cc
+++ b/ppapi/examples/video_decode/video_decode.cc
@@ -24,6 +24,7 @@
#include "ppapi/cpp/var.h"
#include "ppapi/examples/video_decode/testdata.h"
#include "ppapi/lib/gl/include/GLES2/gl2.h"
+#include "ppapi/lib/gl/include/GLES2/gl2ext.h"
#include "ppapi/utility/completion_callback_factory.h"
// Use assert as a poor-man's CHECK, even in non-debug mode.
@@ -39,6 +40,19 @@
namespace {
+struct PictureBufferInfo {
+ PP_PictureBuffer_Dev buffer;
+ GLenum texture_target;
+};
+
+struct Shader {
+ Shader() : program(0),
+ texcoord_scale_location(0) {}
+
+ GLuint program;
+ GLint texcoord_scale_location;
+};
+
class VideoDecodeDemoInstance : public pp::Instance,
public pp::Graphics3DClient,
public pp::VideoDecoderClient_Dev {
@@ -90,7 +104,7 @@ class VideoDecodeDemoInstance : public pp::Instance,
uint32_t texture_target);
void DismissPictureBuffer(int32_t picture_buffer_id);
- const PP_PictureBuffer_Dev& GetPictureBufferById(int id);
+ const PictureBufferInfo& GetPictureBufferInfoById(int id);
pp::VideoDecoder_Dev* decoder() { return decoder_; }
private:
@@ -107,7 +121,7 @@ class VideoDecodeDemoInstance : public pp::Instance,
size_t encoded_data_next_pos_to_decode_;
std::set<int> bitstream_ids_at_decoder_;
// Map of texture buffers indexed by buffer id.
- typedef std::map<int, PP_PictureBuffer_Dev> PictureBufferMap;
+ typedef std::map<int, PictureBufferInfo> PictureBufferMap;
PictureBufferMap picture_buffers_by_id_;
// Map of bitstream buffers indexed by id.
typedef std::map<int, pp::Buffer_Dev*> BitstreamBufferMap;
@@ -119,8 +133,10 @@ class VideoDecodeDemoInstance : public pp::Instance,
// GL-related functions.
void InitGL();
- GLuint CreateTexture(int32_t width, int32_t height);
+ GLuint CreateTexture(int32_t width, int32_t height, GLenum texture_target);
void CreateGLObjects();
+ Shader CreateProgram(const char* vertex_shader,
+ const char* fragment_shader);
void CreateShader(GLuint program, GLenum type, const char* source, int size);
void DeleteTexture(GLuint id);
void PaintFinished(int32_t result, PP_Resource decoder,
@@ -168,6 +184,11 @@ class VideoDecodeDemoInstance : public pp::Instance,
pp::Graphics3D* context_;
typedef std::map<int, DecoderClient*> Decoders;
Decoders video_decoders_;
+
+ // Shader program to draw GL_TEXTURE_2D target.
+ Shader shader_2d_;
+ // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target.
+ Shader shader_rectangle_arb_;
};
VideoDecodeDemoInstance::DecoderClient::DecoderClient(
@@ -189,7 +210,7 @@ VideoDecodeDemoInstance::DecoderClient::~DecoderClient() {
for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin();
it != picture_buffers_by_id_.end(); ++it) {
- gles2_->DeleteTexture(it->second.texture_id);
+ gles2_->DeleteTexture(it->second.buffer.texture_id);
}
picture_buffers_by_id_.clear();
}
@@ -212,6 +233,13 @@ VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance,
}
VideoDecodeDemoInstance::~VideoDecodeDemoInstance() {
+ if (shader_2d_.program)
+ gles2_if_->DeleteProgram(context_->pp_resource(), shader_2d_.program);
+ if (shader_rectangle_arb_.program) {
+ gles2_if_->DeleteProgram(
+ context_->pp_resource(), shader_rectangle_arb_.program);
+ }
+
for (Decoders::iterator it = video_decoders_.begin();
it != video_decoders_.end(); ++it) {
delete it->second;
@@ -337,24 +365,23 @@ void VideoDecodeDemoInstance::DecoderClient::ProvidePictureBuffers(
uint32_t req_num_of_bufs,
PP_Size dimensions,
uint32_t texture_target) {
- // TODO(sail): Add support for GL_TEXTURE_RECTANGLE_ARB.
- assert(texture_target == GL_TEXTURE_2D);
std::vector<PP_PictureBuffer_Dev> buffers;
for (uint32_t i = 0; i < req_num_of_bufs; ++i) {
- PP_PictureBuffer_Dev buffer;
- buffer.size = dimensions;
- buffer.texture_id =
- gles2_->CreateTexture(dimensions.width, dimensions.height);
+ PictureBufferInfo info;
+ info.buffer.size = dimensions;
+ info.texture_target = texture_target;
+ info.buffer.texture_id = gles2_->CreateTexture(
+ dimensions.width, dimensions.height, info.texture_target);
int id = ++next_picture_buffer_id_;
- buffer.id = id;
- buffers.push_back(buffer);
- assert(picture_buffers_by_id_.insert(std::make_pair(id, buffer)).second);
+ info.buffer.id = id;
+ buffers.push_back(info.buffer);
+ assert(picture_buffers_by_id_.insert(std::make_pair(id, info)).second);
}
decoder_->AssignPictureBuffers(buffers);
}
-const PP_PictureBuffer_Dev&
-VideoDecodeDemoInstance::DecoderClient::GetPictureBufferById(
+const PictureBufferInfo&
+VideoDecodeDemoInstance::DecoderClient::GetPictureBufferInfoById(
int id) {
PictureBufferMap::iterator it = picture_buffers_by_id_.find(id);
assert(it != picture_buffers_by_id_.end());
@@ -370,7 +397,8 @@ void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder,
void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer(
int32_t picture_buffer_id) {
- gles2_->DeleteTexture(GetPictureBufferById(picture_buffer_id).texture_id);
+ gles2_->DeleteTexture(GetPictureBufferInfoById(
+ picture_buffer_id).buffer.texture_id);
picture_buffers_by_id_.erase(picture_buffer_id);
}
@@ -384,8 +412,8 @@ void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder,
}
DecoderClient* client = video_decoders_[decoder];
assert(client);
- const PP_PictureBuffer_Dev& buffer =
- client->GetPictureBufferById(picture.picture_buffer_id);
+ const PictureBufferInfo& info =
+ client->GetPictureBufferInfoById(picture.picture_buffer_id);
assert(!is_painting_);
is_painting_ = true;
int x = 0;
@@ -395,16 +423,33 @@ void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder,
y = plugin_size_.height() / kNumDecoders;
}
+ if (info.texture_target == GL_TEXTURE_2D) {
+ gles2_if_->UseProgram(context_->pp_resource(), shader_2d_.program);
+ gles2_if_->Uniform2f(
+ context_->pp_resource(), shader_2d_.texcoord_scale_location, 1.0, 1.0);
+ } else {
+ assert(info.texture_target == GL_TEXTURE_RECTANGLE_ARB);
+ gles2_if_->UseProgram(
+ context_->pp_resource(), shader_rectangle_arb_.program);
+ gles2_if_->Uniform2f(context_->pp_resource(),
+ shader_rectangle_arb_.texcoord_scale_location,
+ info.buffer.size.width,
+ info.buffer.size.height);
+ }
+
gles2_if_->Viewport(context_->pp_resource(), x, y,
plugin_size_.width() / kNumDecoders,
plugin_size_.height() / kNumDecoders);
gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
gles2_if_->BindTexture(
- context_->pp_resource(), GL_TEXTURE_2D, buffer.texture_id);
+ context_->pp_resource(), info.texture_target, info.buffer.texture_id);
gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4);
+
+ gles2_if_->UseProgram(context_->pp_resource(), 0);
+
pp::CompletionCallback cb =
callback_factory_.NewCallback(
- &VideoDecodeDemoInstance::PaintFinished, decoder, buffer.id);
+ &VideoDecodeDemoInstance::PaintFinished, decoder, info.buffer.id);
last_swap_request_ticks_ = core_if_->GetTimeTicks();
assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING);
}
@@ -483,29 +528,33 @@ void VideoDecodeDemoInstance::PaintFinished(int32_t result, PP_Resource decoder,
}
}
-GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width, int32_t height) {
+GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width,
+ int32_t height,
+ GLenum texture_target) {
GLuint texture_id;
gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id);
assertNoGLError();
// Assign parameters.
gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
- gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id);
+ gles2_if_->BindTexture(context_->pp_resource(), texture_target, texture_id);
gles2_if_->TexParameteri(
- context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ context_->pp_resource(), texture_target, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
gles2_if_->TexParameteri(
- context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ context_->pp_resource(), texture_target, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
gles2_if_->TexParameterf(
- context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+ context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
gles2_if_->TexParameterf(
- context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+ context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
- gles2_if_->TexImage2D(
- context_->pp_resource(), GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ if (texture_target == GL_TEXTURE_2D) {
+ gles2_if_->TexImage2D(
+ context_->pp_resource(), texture_target, 0, GL_RGBA, width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
assertNoGLError();
return texture_id;
}
@@ -520,13 +569,14 @@ void VideoDecodeDemoInstance::CreateGLObjects() {
"varying vec2 v_texCoord; \n"
"attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
+ "uniform vec2 v_scale; \n"
"void main() \n"
"{ \n"
- " v_texCoord = a_texCoord; \n"
+ " v_texCoord = v_scale * a_texCoord; \n"
" gl_Position = a_position; \n"
"}";
- static const char kFragmentShader[] =
+ static const char kFragmentShader2D[] =
"precision mediump float; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
@@ -535,38 +585,63 @@ void VideoDecodeDemoInstance::CreateGLObjects() {
" gl_FragColor = texture2D(s_texture, v_texCoord); \n"
"}";
- // Create shader program.
- GLuint program = gles2_if_->CreateProgram(context_->pp_resource());
- CreateShader(program, GL_VERTEX_SHADER, kVertexShader, sizeof(kVertexShader));
- CreateShader(
- program, GL_FRAGMENT_SHADER, kFragmentShader, sizeof(kFragmentShader));
- gles2_if_->LinkProgram(context_->pp_resource(), program);
- gles2_if_->UseProgram(context_->pp_resource(), program);
- gles2_if_->DeleteProgram(context_->pp_resource(), program);
- gles2_if_->Uniform1i(
- context_->pp_resource(),
- gles2_if_->GetUniformLocation(
- context_->pp_resource(), program, "s_texture"), 0);
- assertNoGLError();
+ static const char kFragmentShaderRectangle[] =
+ "#extension GL_ARB_texture_rectangle : require\n"
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2DRect s_texture; \n"
+ "void main() \n"
+ "{"
+ " gl_FragColor = texture2DRect(s_texture, v_texCoord).rgba; \n"
+ "}";
// Assign vertex positions and texture coordinates to buffers for use in
// shader program.
static const float kVertices[] = {
-1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates.
- 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates.
+ 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates.
};
GLuint buffer;
gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer);
gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer);
+
gles2_if_->BufferData(context_->pp_resource(), GL_ARRAY_BUFFER,
sizeof(kVertices), kVertices, GL_STATIC_DRAW);
assertNoGLError();
+
+ shader_2d_ = CreateProgram(kVertexShader, kFragmentShader2D);
+ shader_rectangle_arb_ =
+ CreateProgram(kVertexShader, kFragmentShaderRectangle);
+}
+
+Shader VideoDecodeDemoInstance::CreateProgram(const char* vertex_shader,
+ const char* fragment_shader) {
+ Shader shader;
+
+ // Create shader program.
+ shader.program = gles2_if_->CreateProgram(context_->pp_resource());
+ CreateShader(shader.program, GL_VERTEX_SHADER, vertex_shader,
+ strlen(vertex_shader));
+ CreateShader(shader.program, GL_FRAGMENT_SHADER, fragment_shader,
+ strlen(fragment_shader));
+ gles2_if_->LinkProgram(context_->pp_resource(), shader.program);
+ gles2_if_->UseProgram(context_->pp_resource(), shader.program);
+ gles2_if_->Uniform1i(
+ context_->pp_resource(),
+ gles2_if_->GetUniformLocation(
+ context_->pp_resource(), shader.program, "s_texture"), 0);
+ assertNoGLError();
+
+ shader.texcoord_scale_location = gles2_if_->GetUniformLocation(
+ context_->pp_resource(), shader.program, "v_scale");
+
GLint pos_location = gles2_if_->GetAttribLocation(
- context_->pp_resource(), program, "a_position");
+ context_->pp_resource(), shader.program, "a_position");
GLint tc_location = gles2_if_->GetAttribLocation(
- context_->pp_resource(), program, "a_texCoord");
+ context_->pp_resource(), shader.program, "a_texCoord");
assertNoGLError();
+
gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location);
gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2,
GL_FLOAT, GL_FALSE, 0, 0);
@@ -574,7 +649,10 @@ void VideoDecodeDemoInstance::CreateGLObjects() {
gles2_if_->VertexAttribPointer(
context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0,
static_cast<float*>(0) + 8); // Skip position coordinates.
+
+ gles2_if_->UseProgram(context_->pp_resource(), 0);
assertNoGLError();
+ return shader;
}
void VideoDecodeDemoInstance::CreateShader(