Index: content/common/gpu/media/rendering_helper.cc |
diff --git a/content/common/gpu/media/rendering_helper.cc b/content/common/gpu/media/rendering_helper.cc |
index 3cdbf33309a0b941963f45984f40bd7728fc1d41..ac18fdc493c22b6b25d0e98ef817694551edb07a 100644 |
--- a/content/common/gpu/media/rendering_helper.cc |
+++ b/content/common/gpu/media/rendering_helper.cc |
@@ -4,6 +4,10 @@ |
#include "content/common/gpu/media/rendering_helper.h" |
+#include <algorithm> |
+#include <numeric> |
+#include <vector> |
+ |
#include "base/bind.h" |
#include "base/mac/scoped_nsautorelease_pool.h" |
#include "base/message_loop/message_loop.h" |
@@ -82,16 +86,16 @@ RenderingHelper::RenderingHelper() { |
} |
RenderingHelper::~RenderingHelper() { |
- CHECK_EQ(frame_dimensions_.size(), 0U) |
+ CHECK_EQ(clients_.size(), 0U) |
<< "Must call UnInitialize before dtor."; |
Clear(); |
} |
void RenderingHelper::Initialize(const RenderingHelperParams& params, |
base::WaitableEvent* done) { |
- // Use frame_dimensions_.size() != 0 as a proxy for the class having already |
- // been Initialize()'d, and UnInitialize() before continuing. |
- if (frame_dimensions_.size()) { |
+ // Use cients_.size() != 0 as a proxy for the class having already been |
+ // Initialize()'d, and UnInitialize() before continuing. |
+ if (clients_.size()) { |
base::WaitableEvent done(false, false); |
UnInitialize(&done); |
done.Wait(); |
@@ -105,14 +109,8 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( |
new gfx::GLContextStubWithExtensions()); |
- CHECK_GT(params.window_dimensions.size(), 0U); |
- CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size()); |
- frame_dimensions_ = params.frame_dimensions; |
render_as_thumbnails_ = params.render_as_thumbnails; |
message_loop_ = base::MessageLoop::current(); |
- CHECK_GT(params.num_windows, 0); |
- |
- gfx::Size window_size; |
#if GL_VARIANT_GLX |
x_display_ = gfx::GetXDisplay(); |
@@ -142,13 +140,13 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
reinterpret_cast<const char*>(glGetString(GL_VERSION))); |
Screen* screen = DefaultScreenOfDisplay(x_display_); |
- window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); |
+ screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); |
#else // EGL |
EGLNativeDisplayType native_display; |
#if defined(OS_WIN) |
native_display = EGL_DEFAULT_DISPLAY; |
- window_size = |
+ screen_size_ = |
gfx::Size(GetSystemMetrics(SM_CXSREEN), GetSystemMetrics(SM_CY_SCREEN)) |
#else |
x_display_ = gfx::GetXDisplay(); |
@@ -156,7 +154,7 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
native_display = x_display_; |
Screen* screen = DefaultScreenOfDisplay(x_display_); |
- window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); |
+ screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); |
#endif |
gl_display_ = eglGetDisplay(native_display); |
CHECK(gl_display_); |
@@ -187,18 +185,8 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
reinterpret_cast<const char*>(glGetString(GL_VERSION))); |
#endif |
clients_ = params.clients; |
- // Per-window/surface X11 & EGL initialization. |
- for (int i = 0; i < params.num_windows; ++i) { |
- // Arrange X windows whimsically, with some padding. |
- int j = i % params.window_dimensions.size(); |
- int width = params.window_dimensions[j].width(); |
- int height = params.window_dimensions[j].height(); |
- CHECK_GT(width, 0); |
- CHECK_GT(height, 0); |
- int top_left_x = (width + 20) * (i % 4); |
- int top_left_y = (height + 12) * (i % 3); |
- render_areas_.push_back(gfx::Rect(top_left_x, top_left_y, width, height)); |
- } |
+ CHECK_GT(clients_.size(), 0); |
+ LayoutRenderingAreas(); |
#if defined(OS_WIN) |
window_ = CreateWindowEx(0, |
@@ -207,8 +195,8 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
WS_OVERLAPPEDWINDOW | WS_VISIBLE, |
0, |
0, |
- window_size.width(), |
- widow_size.height(), |
+ screen_size_.width(), |
+ screen_size_.height(), |
NULL, |
NULL, |
NULL, |
@@ -230,8 +218,8 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
DefaultRootWindow(x_display_), |
0, |
0, |
- window_size.width(), |
- window_size.height(), |
+ screen_size_.width(), |
+ screen_size_.height(), |
0 /* border width */, |
depth, |
CopyFromParent /* class */, |
@@ -260,7 +248,7 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get()); |
if (render_as_thumbnails_) { |
- CHECK_EQ(frame_dimensions_.size(), 1U); |
+ CHECK_EQ(clients_.size(), 1U); |
GLint max_texture_size; |
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); |
@@ -405,26 +393,25 @@ void RenderingHelper::UnInitialize(base::WaitableEvent* done) { |
done->Signal(); |
} |
-void RenderingHelper::CreateTexture(int window_id, |
- uint32 texture_target, |
+void RenderingHelper::CreateTexture(uint32 texture_target, |
uint32* texture_id, |
+ const gfx::Size& size, |
base::WaitableEvent* done) { |
if (base::MessageLoop::current() != message_loop_) { |
message_loop_->PostTask( |
FROM_HERE, |
base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), |
- window_id, texture_target, texture_id, done)); |
+ texture_target, texture_id, size, done)); |
return; |
} |
glGenTextures(1, texture_id); |
glBindTexture(texture_target, *texture_id); |
- int dimensions_id = window_id % frame_dimensions_.size(); |
if (texture_target == GL_TEXTURE_2D) { |
glTexImage2D(GL_TEXTURE_2D, |
0, |
GL_RGBA, |
- frame_dimensions_[dimensions_id].width(), |
- frame_dimensions_[dimensions_id].height(), |
+ size.width(), |
+ size.height(), |
0, |
GL_RGBA, |
GL_UNSIGNED_BYTE, |
@@ -436,8 +423,6 @@ void RenderingHelper::CreateTexture(int window_id, |
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
- CHECK(texture_id_to_surface_index_.insert( |
- std::make_pair(*texture_id, window_id)).second); |
done->Signal(); |
} |
@@ -502,8 +487,7 @@ void* RenderingHelper::GetGLDisplay() { |
} |
void RenderingHelper::Clear() { |
- frame_dimensions_.clear(); |
- texture_id_to_surface_index_.clear(); |
+ clients_.clear(); |
message_loop_ = NULL; |
gl_context_ = NULL; |
#if GL_VARIANT_EGL |
@@ -592,4 +576,64 @@ void RenderingHelper::RenderContent() { |
CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); |
#endif |
} |
+ |
+// Helper function to scale the lengths to match the total_length and |
+// calculate the offsets. |
Ami GONE FROM CHROMIUM
2014/05/27 16:05:25
This comment isn't adding value because the non-co
Owen Lin
2014/05/28 06:55:18
The comment is modified. Thanks.
|
+static void ScaleAndCalculateOffsets(std::vector<int>& lengths, |
Ami GONE FROM CHROMIUM
2014/05/27 16:05:25
const ref or non-const ptr, never non-const ref.
h
Owen Lin
2014/05/28 06:55:18
Done.
|
+ std::vector<int>& offsets, |
+ int total_length) { |
+ int sum = std::accumulate(lengths.begin(), lengths.end(), 0); |
+ for (size_t i = 0; i < lengths.size(); ++i) { |
+ lengths[i] = lengths[i] * total_length / sum; |
+ if (i > 0) |
+ offsets[i] = offsets[i - 1] + lengths[i - 1]; |
Ami GONE FROM CHROMIUM
2014/05/27 16:05:25
else
offsets[0] = 0;
Owen Lin
2014/05/28 06:55:18
Done.
|
+ } |
+} |
+ |
+void RenderingHelper::LayoutRenderingAreas() { |
+ size_t cols, rows; |
+ |
+ // Find the number of colums and rows. The smallest n * n or n * (n + 1). |
+ for (rows = 1;; ++rows) { |
+ cols = rows; |
+ if (cols * rows >= clients_.size()) |
+ break; |
+ cols = rows + 1; |
+ if (cols * rows >= clients_.size()) |
+ break; |
+ } |
Ami GONE FROM CHROMIUM
2014/05/27 16:05:25
are l.594-604 equiv to
size_t rows = sqrt(clients_
Owen Lin
2014/05/28 06:55:18
Done. Thanks.
|
+ |
+ // Find the widths and heights of the grid. |
+ std::vector<int> widths(cols); |
+ std::vector<int> heights(rows); |
+ std::vector<int> offset_x(cols); |
+ std::vector<int> offset_y(rows); |
+ |
+ for (size_t i = 0; i < clients_.size(); ++i) { |
+ const gfx::Size &window_size = clients_[i]->GetWindowSize(); |
+ widths[i % cols] = std::max(widths[i % cols], window_size.width()); |
+ heights[i / cols] = std::max(heights[i / cols], window_size.height()); |
+ } |
+ |
+ ScaleAndCalculateOffsets(widths, offset_x, screen_size_.width()); |
+ ScaleAndCalculateOffsets(heights, offset_y, screen_size_.height()); |
+ |
+ // Put each render_area_ in the center of each cell. |
+ render_areas_.clear(); |
+ for (size_t i = 0; i < clients_.size(); ++i) { |
+ const gfx::Size &window_size = clients_[i]->GetWindowSize(); |
Ami GONE FROM CHROMIUM
2014/05/27 16:05:25
nit: & sticks left not right
Owen Lin
2014/05/28 06:55:18
Done.
|
+ float scale = std::min( |
+ static_cast<float>(widths[i % cols]) / window_size.width(), |
+ static_cast<float>(heights[i / cols]) / window_size.height()); |
+ |
+ // Don't scale up the texture. |
+ scale = std::min(1.0f, scale); |
+ |
+ size_t w = scale * window_size.width(); |
+ size_t h = scale * window_size.height(); |
+ size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; |
+ size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; |
+ render_areas_.push_back(gfx::Rect(x, y, w, h)); |
+ } |
+} |
} // namespace content |