summaryrefslogtreecommitdiffstats
path: root/ppapi/examples
diff options
context:
space:
mode:
authorfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-12 16:04:26 +0000
committerfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-12 16:04:26 +0000
commit39c7f2913c9c6e37ec037f004cf3eed7565a1d4a (patch)
tree631e51a15e27ca0cb3ea9ff06bf7cabb12c628d3 /ppapi/examples
parent94c86e1fcf25b6e879a7198211fc3a9a45eb2e53 (diff)
downloadchromium_src-39c7f2913c9c6e37ec037f004cf3eed7565a1d4a.zip
chromium_src-39c7f2913c9c6e37ec037f004cf3eed7565a1d4a.tar.gz
chromium_src-39c7f2913c9c6e37ec037f004cf3eed7565a1d4a.tar.bz2
Cleanup gles2 sample PPAPI plugin.
- Queue decoded frames when render (SwapBuffers) is still in progress instead of dropping them. - Emit timing information (fps & ms/swap) to evaluate performance options. - Simplify GL initialization/setup and make it closer to what OmxVideoDecodeAcceleratorTest does, for apples-to-apples performance comparison. - Remove no-longer-necessary HTML styling (which probably became obsolete when I fixed the first-page-load crashes caused by GL double-initialization). BUG=none TEST=gles2 runs Review URL: http://codereview.chromium.org/7237054 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92177 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/examples')
-rw-r--r--ppapi/examples/gles2/gles2.cc157
-rw-r--r--ppapi/examples/gles2/gles2.html12
2 files changed, 76 insertions, 93 deletions
diff --git a/ppapi/examples/gles2/gles2.cc b/ppapi/examples/gles2/gles2.cc
index 62e0711..60c5bdf 100644
--- a/ppapi/examples/gles2/gles2.cc
+++ b/ppapi/examples/gles2/gles2.cc
@@ -5,9 +5,11 @@
#include <string.h>
#include <iostream>
+#include <list>
#include <map>
#include <set>
#include <vector>
+
#include "ppapi/c/dev/ppb_opengles_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/dev/context_3d_dev.h"
@@ -28,6 +30,11 @@
#undef NDEBUG
#include <assert.h>
+// Assert |context_| isn't holding any GL Errors. Done as a macro instead of a
+// function to preserve line number information in the failure message.
+#define assertNoGLError() \
+ assert(!gles2_if_->GetError(context_->pp_resource()));
+
namespace {
class GLES2DemoInstance : public pp::Instance, public pp::Graphics3DClient_Dev,
@@ -64,14 +71,6 @@ class GLES2DemoInstance : public pp::Instance, public pp::Graphics3DClient_Dev,
private:
enum { kNumConcurrentDecodes = 7 };
- // Helper struct that stores data used by the shader program.
- struct ShaderInfo {
- GLint pos_location;
- GLint tc_location;
- GLint tex_location;
- GLuint vertex_buffers[2];
- };
-
// Initialize Video Decoder.
void InitializeDecoder();
@@ -95,19 +94,17 @@ class GLES2DemoInstance : public pp::Instance, public pp::Graphics3DClient_Dev,
void DeleteTexture(GLuint id);
void PaintFinished(int32_t result, int picture_buffer_id);
- // Assert |context_| isn't holding any GL Errors.
- void assertNoGLError() {
- assert(!gles2_if_->GetError(context_->pp_resource()));
- }
-
pp::Size position_size_;
- ShaderInfo program_data_;
int next_picture_buffer_id_;
int next_bitstream_buffer_id_;
bool is_painting_;
pp::CompletionCallbackFactory<GLES2DemoInstance> callback_factory_;
size_t encoded_data_next_pos_to_decode_;
std::set<int> bitstream_ids_at_decoder_;
+ // When decode outpaces render, we queue up decoded pictures for later
+ // painting.
+ std::list<PP_Picture_Dev> pictures_pending_paint_;
+ int num_frames_rendered_;
// Map of texture buffers indexed by buffer id.
typedef std::map<int, PP_GLESBuffer_Dev> PictureBufferMap;
@@ -115,8 +112,12 @@ class GLES2DemoInstance : public pp::Instance, public pp::Graphics3DClient_Dev,
// Map of bitstream buffers indexed by id.
typedef std::map<int, pp::Buffer_Dev*> BitstreamBufferMap;
BitstreamBufferMap bitstream_buffers_by_id_;
+ PP_TimeTicks first_frame_delivered_ticks_;
+ PP_TimeTicks last_swap_request_ticks_;
+ PP_TimeTicks swap_ticks_;
// Unowned pointers.
+ const struct PPB_Core* core_if_;
const struct PPB_OpenGLES2_Dev* gles2_if_;
// Owned data.
@@ -132,12 +133,16 @@ GLES2DemoInstance::GLES2DemoInstance(PP_Instance instance, pp::Module* module)
next_bitstream_buffer_id_(0),
callback_factory_(this),
encoded_data_next_pos_to_decode_(0),
+ num_frames_rendered_(0),
+ first_frame_delivered_ticks_(-1),
+ swap_ticks_(0),
context_(NULL),
surface_(NULL),
video_decoder_(NULL) {
- gles2_if_ = static_cast<const struct PPB_OpenGLES2_Dev*>(
- module->GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE));
- assert(gles2_if_);
+ assert((core_if_ = static_cast<const struct PPB_Core*>(
+ module->GetBrowserInterface(PPB_CORE_INTERFACE))));
+ assert((gles2_if_ = static_cast<const struct PPB_OpenGLES2_Dev*>(
+ module->GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE))));
}
GLES2DemoInstance::~GLES2DemoInstance() {
@@ -162,8 +167,7 @@ void GLES2DemoInstance::DidChangeView(
}
void GLES2DemoInstance::InitializeDecoder() {
- if (video_decoder_)
- return;
+ assert(!video_decoder_);
video_decoder_ = new pp::VideoDecoder_Dev(*this);
PP_VideoConfigElement configs = PP_VIDEOATTR_DICTIONARY_TERMINATOR;
@@ -276,6 +280,12 @@ void GLES2DemoInstance::DismissPictureBuffer(
void GLES2DemoInstance::PictureReady(
pp::VideoDecoder_Dev decoder, const PP_Picture_Dev& picture) {
+ if (first_frame_delivered_ticks_ == -1)
+ assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1);
+ if (is_painting_) {
+ pictures_pending_paint_.push_back(picture);
+ return;
+ }
PictureBufferMap::iterator it =
buffers_by_id_.find(picture.picture_buffer_id);
assert(it != buffers_by_id_.end());
@@ -331,30 +341,37 @@ void GLES2DemoInstance::InitGL() {
}
void GLES2DemoInstance::Render(const PP_GLESBuffer_Dev& buffer) {
- if (is_painting_) {
- // We are dropping frames if we don't render fast enough -
- // that is why sometimes the last frame rendered is < 249.
- if (video_decoder_)
- video_decoder_->ReusePictureBuffer(buffer.info.id);
- return;
- }
+ assert(!is_painting_);
is_painting_ = true;
gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
gles2_if_->BindTexture(
context_->pp_resource(), GL_TEXTURE_2D, buffer.texture_id);
- gles2_if_->Uniform1i(context_->pp_resource(), program_data_.tex_location, 0);
gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4);
pp::CompletionCallback cb =
callback_factory_.NewCallback(
&GLES2DemoInstance::PaintFinished, buffer.info.id);
+ last_swap_request_ticks_ = core_if_->GetTimeTicks();
assert(surface_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING);
- assertNoGLError();
}
void GLES2DemoInstance::PaintFinished(int32_t result, int picture_buffer_id) {
+ swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_;
is_painting_ = false;
- if (video_decoder_)
- video_decoder_->ReusePictureBuffer(picture_buffer_id);
+ ++num_frames_rendered_;
+ if (num_frames_rendered_ % 50 == 0) {
+ double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_;
+ double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000;
+ double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_;
+ std::cerr << "Rendered frames: " << num_frames_rendered_ << ", fps: "
+ << fps << ", with average ms/swap of: " << ms_per_swap
+ << std::endl;
+ }
+ video_decoder_->ReusePictureBuffer(picture_buffer_id);
+ while (!pictures_pending_paint_.empty() && !is_painting_) {
+ PP_Picture_Dev picture = pictures_pending_paint_.front();
+ pictures_pending_paint_.pop_front();
+ PictureReady(*video_decoder_, picture);
+ }
}
GLuint GLES2DemoInstance::CreateTexture(int32_t width, int32_t height) {
@@ -404,47 +421,13 @@ void GLES2DemoInstance::CreateGLObjects() {
static const char kFragmentShader[] =
"precision mediump float; \n"
- "precision mediump int; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
"{"
- " vec4 value = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
- " gl_FragColor = vec4(value.rgb, 1); \n"
+ " gl_FragColor = texture2D(s_texture, v_texCoord); \n"
"}";
- static const GLfloat kVertices[] = {
- -1.f, 1.f, // Position 0
- 0.0f, 0.0f, // TexCoord 0
- -1.f, -1.f, // Position 1
- 0.0f, 1.0f, // TexCoord 1
- 1.f, 1.f, // Position 2
- 1.0f, 0.0f, // TexCoord 2
- 1.0f, -1.f, // Position 3
- 1.0f, 1.0f // TexCoord 3
- };
-
- static const GLushort kIndices[] = { 0, 1, 2, 3 };
-
- // Create vertex position and texture coordinate buffers.
- gles2_if_->GenBuffers(
- context_->pp_resource(), 2, program_data_.vertex_buffers);
-
- // Creates and binds vertex/texture data to buffers.
- gles2_if_->BindBuffer(
- context_->pp_resource(), GL_ARRAY_BUFFER,
- program_data_.vertex_buffers[0]);
- gles2_if_->BufferData(
- context_->pp_resource(), GL_ARRAY_BUFFER, sizeof(kVertices),
- kVertices, GL_STATIC_DRAW);
- gles2_if_->BindBuffer(
- context_->pp_resource(),GL_ELEMENT_ARRAY_BUFFER,
- program_data_.vertex_buffers[1]);
- gles2_if_->BufferData(
- context_->pp_resource(),GL_ELEMENT_ARRAY_BUFFER,
- sizeof(kIndices), kIndices, GL_STATIC_DRAW);
- assertNoGLError();
-
// Create shader program.
GLuint program = gles2_if_->CreateProgram(context_->pp_resource());
CreateShader(program, GL_VERTEX_SHADER, kVertexShader, sizeof(kVertexShader));
@@ -453,31 +436,37 @@ void GLES2DemoInstance::CreateGLObjects() {
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_->GetAttribLocation(
+ context_->pp_resource(), program, "s_texture"), 0);
assertNoGLError();
- // Remember locations for shader variables.
- program_data_.pos_location = gles2_if_->GetAttribLocation(
+ // 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.
+ };
+
+ 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();
+ GLint pos_location = gles2_if_->GetAttribLocation(
context_->pp_resource(), program, "a_position");
- program_data_.tc_location = gles2_if_->GetAttribLocation(
+ GLint tc_location = gles2_if_->GetAttribLocation(
context_->pp_resource(), program, "a_texCoord");
- program_data_.tex_location = gles2_if_->GetAttribLocation(
- context_->pp_resource(), program, "s_texture");
assertNoGLError();
-
- // Assign vertex positions and texture coordinates to buffers for use in
- // shader program.
- GLfloat* ptr = (GLfloat*) 0;
- gles2_if_->VertexAttribPointer(
- context_->pp_resource(), program_data_.pos_location, 2, GL_FLOAT,
- GL_FALSE, 4 * sizeof(GLfloat), ptr);
- gles2_if_->EnableVertexAttribArray(
- context_->pp_resource(), program_data_.pos_location);
- ptr += 2;
+ gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location);
+ gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2,
+ GL_FLOAT, GL_FALSE, 0, 0);
+ gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location);
gles2_if_->VertexAttribPointer(
- context_->pp_resource(), program_data_.tc_location, 2, GL_FLOAT,
- GL_FALSE, 4 * sizeof(GLfloat), ptr);
- gles2_if_->EnableVertexAttribArray(
- context_->pp_resource(), program_data_.tc_location);
+ context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0,
+ static_cast<float*>(0) + 8); // Skip position coordinates.
assertNoGLError();
}
diff --git a/ppapi/examples/gles2/gles2.html b/ppapi/examples/gles2/gles2.html
index 798732e..887e094 100644
--- a/ppapi/examples/gles2/gles2.html
+++ b/ppapi/examples/gles2/gles2.html
@@ -9,16 +9,10 @@
<title>GLES2 Example</title>
</head>
-<body style="background-color:Silver">
+<body>
-<!--
-TODO(vrk/fischman):
-It seems the plugin crashes unless this "-webkit-transform" style is
-in place. Seems to be a problem with lost context.
--->
-<embed id="plugin" type="application/x-ppapi-example-gles2"
- style="-webkit-transform: rotateY(-0deg);"
- width="320" height="240"/>
+<embed id="plugin" type="application/x-ppapi-example-gles2"
+ width="320" height="240"/>
</body>
</html>