Skip to content

Commit

Permalink
[BrowserTag] Send dib info with NavigateGuest message,
Browse files Browse the repository at this point in the history
This would fix guest painting in: set no src + resize + navigate to src case.

Without this change, for the scenario above, we don't get any dib at all from
embedder upon setting the non-empty src. Now we also ship dib on NavigateGuest
if necessary. This dib is the last accumulated dib from updateGeometry().

Note that our unit test exercises this case, but doesn't look for correct
painting, it only expects UpdateRect to be called with correct size. I've updated the test now to look for correct sized damage buffer instead.


BUG=151948
TEST= Create an empty src guest and keep changing its size in
SetInterval from the embedder, then in the middle set a non-empty src. Observed
that guest paints correctly with final size. Updated unit test to look for damage buffer with correct size instead of looking for UpdateRect with correct size.

Review URL: https://chromiumcodereview.appspot.com/10965048

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159404 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
lazyboy@chromium.org committed Sep 29, 2012
1 parent 50cedc2 commit 92a01cc
Show file tree
Hide file tree
Showing 16 changed files with 321 additions and 222 deletions.
77 changes: 57 additions & 20 deletions content/browser/browser_plugin/browser_plugin_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "content/browser/browser_plugin/browser_plugin_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/browser_plugin_messages.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
Expand Down Expand Up @@ -76,10 +77,11 @@ void BrowserPluginEmbedder::AddGuest(int instance_id,
guest_web_contents_by_instance_id_[instance_id] = guest_web_contents;
}

void BrowserPluginEmbedder::NavigateGuest(RenderViewHost* render_view_host,
int instance_id,
const std::string& src,
const gfx::Size& size) {
void BrowserPluginEmbedder::NavigateGuest(
RenderViewHost* render_view_host,
int instance_id,
const std::string& src,
const BrowserPluginHostMsg_ResizeGuest_Params& resize_params) {
BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
WebContentsImpl* guest_web_contents = NULL;
GURL url(src);
Expand Down Expand Up @@ -125,8 +127,8 @@ void BrowserPluginEmbedder::NavigateGuest(RenderViewHost* render_view_host,
std::string());
}

if (!size.IsEmpty())
guest_web_contents->GetView()->SizeContents(size);
// Resize the guest if the resize parameter was set from the renderer.
ResizeGuest(render_view_host, instance_id, resize_params);
}

void BrowserPluginEmbedder::UpdateRectACK(int instance_id,
Expand All @@ -137,28 +139,63 @@ void BrowserPluginEmbedder::UpdateRectACK(int instance_id,
guest->UpdateRectACK(message_id, size);
}

void BrowserPluginEmbedder::ResizeGuest(int instance_id,
TransportDIB* damage_buffer,
#if defined(OS_WIN)
int damage_buffer_size,
#endif
int width,
int height,
bool resize_pending,
float scale_factor) {
void BrowserPluginEmbedder::ResizeGuest(
RenderViewHost* render_view_host,
int instance_id,
const BrowserPluginHostMsg_ResizeGuest_Params& params) {
BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
if (!guest)
return;
WebContentsImpl* guest_web_contents =
static_cast<WebContentsImpl*>(guest->GetWebContents());

if (!TransportDIB::is_valid_id(params.damage_buffer_id)) {
// Invalid transport dib, so just resize the WebContents.
if (params.width && params.height) {
guest_web_contents->GetView()->SizeContents(gfx::Size(params.width,
params.height));
}
return;
}

TransportDIB* damage_buffer = GetDamageBuffer(render_view_host, params);
guest->SetDamageBuffer(damage_buffer,
#if defined(OS_WIN)
damage_buffer_size,
params.damage_buffer_size,
#endif
gfx::Size(width, height),
scale_factor);
if (!resize_pending)
guest_web_contents->GetView()->SizeContents(gfx::Size(width, height));
gfx::Size(params.width, params.height),
params.scale_factor);
if (!params.resize_pending) {
guest_web_contents->GetView()->SizeContents(gfx::Size(params.width,
params.height));
}
}

TransportDIB* BrowserPluginEmbedder::GetDamageBuffer(
RenderViewHost* render_view_host,
const BrowserPluginHostMsg_ResizeGuest_Params& params) {
TransportDIB* damage_buffer = NULL;
#if defined(OS_WIN)
// On Windows we need to duplicate the handle from the remote process.
HANDLE section;
DuplicateHandle(render_view_host->GetProcess()->GetHandle(),
params.damage_buffer_id.handle,
GetCurrentProcess(),
&section,
STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
FALSE,
0);
damage_buffer = TransportDIB::Map(section);
#elif defined(OS_MACOSX)
// On OSX, we need the handle to map the transport dib.
damage_buffer = TransportDIB::Map(params.damage_buffer_handle);
#elif defined(OS_ANDROID)
damage_buffer = TransportDIB::Map(params.damage_buffer_id);
#elif defined(OS_POSIX)
damage_buffer = TransportDIB::Map(params.damage_buffer_id.shmkey);
#endif // defined(OS_POSIX)
DCHECK(damage_buffer);
return damage_buffer;
}

void BrowserPluginEmbedder::SetFocus(int instance_id,
Expand Down
31 changes: 17 additions & 14 deletions content/browser/browser_plugin/browser_plugin_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/surface/transport_dib.h"

class TransportDIB;
class WebContentsImpl;
struct BrowserPluginHostMsg_ResizeGuest_Params;

namespace WebKit {
class WebInputEvent;
Expand Down Expand Up @@ -62,10 +63,16 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver,
RenderViewHost* render_view_host);

// Navigates in a guest (new or existing).
void NavigateGuest(RenderViewHost* render_view_host,
int instance_id,
const std::string& src,
const gfx::Size& size);
void NavigateGuest(
RenderViewHost* render_view_host,
int instance_id,
const std::string& src,
const BrowserPluginHostMsg_ResizeGuest_Params& resize_params);

void ResizeGuest(RenderViewHost* render_view_host,
int instance_id,
const BrowserPluginHostMsg_ResizeGuest_Params& params);

void Go(int instance_id, int relative_index);
void Stop(int instance_id);
void Reload(int instance_id);
Expand All @@ -83,15 +90,6 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver,
// Routes update rect ack message to the appropriate guest.
void UpdateRectACK(int instance_id, int message_id, const gfx::Size& size);
void SetFocus(int instance_id, bool focused);
void ResizeGuest(int instance_id,
TransportDIB* damage_buffer,
#if defined(OS_WIN)
int damage_buffer_size,
#endif
int width,
int height,
bool resize_pending,
float scale_factor);
// Handles input events sent from the BrowserPlugin (embedder's renderer
// process) by passing them to appropriate guest's input handler.
void HandleInputEvent(int instance_id,
Expand Down Expand Up @@ -121,6 +119,11 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver,
void DestroyGuestByInstanceID(int instance_id);
void DestroyGuests();

// Returns the transport DIB associated with the dib in resize |params|.
TransportDIB* GetDamageBuffer(
RenderViewHost* render_view_host,
const BrowserPluginHostMsg_ResizeGuest_Params& params);

// Called when visiblity of web_contents changes, so the embedder will
// show/hide its guest.
void WebContentsVisibilityChanged(bool visible);
Expand Down
46 changes: 9 additions & 37 deletions content/browser/browser_plugin/browser_plugin_embedder_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,39 +54,7 @@ bool BrowserPluginEmbedderHelper::OnMessageReceived(
void BrowserPluginEmbedderHelper::OnResizeGuest(
int instance_id,
const BrowserPluginHostMsg_ResizeGuest_Params& params) {
TransportDIB* damage_buffer = NULL;
#if defined(OS_WIN)
// On Windows we need to duplicate the handle from the remote process.
HANDLE section;
DuplicateHandle(render_view_host()->GetProcess()->GetHandle(),
params.damage_buffer_id.handle,
GetCurrentProcess(),
&section,
STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
FALSE, 0);
damage_buffer = TransportDIB::Map(section);
#elif defined(OS_MACOSX)
// On OSX, the browser allocates all DIBs and keeps a file descriptor around
// for each.
damage_buffer = render_view_host()->GetProcess()->
GetTransportDIB(params.damage_buffer_id);
#elif defined(OS_ANDROID)
damage_buffer = TransportDIB::Map(params.damage_buffer_id);
#elif defined(OS_POSIX)
damage_buffer = TransportDIB::Map(params.damage_buffer_id.shmkey);
#endif // defined(OS_POSIX)
DCHECK(damage_buffer);
// TODO(fsamuel): Schedule this later so that we don't stall the embedder for
// too long.
embedder_->ResizeGuest(instance_id,
damage_buffer,
#if defined(OS_WIN)
params.damage_buffer_size,
#endif
params.width,
params.height,
params.resize_pending,
params.scale_factor);
embedder_->ResizeGuest(render_view_host(), instance_id, params);
}

void BrowserPluginEmbedderHelper::OnHandleInputEvent(
Expand Down Expand Up @@ -129,10 +97,14 @@ void BrowserPluginEmbedderHelper::OnHandleInputEvent(
reply_message);
}

void BrowserPluginEmbedderHelper::OnNavigateGuest(int instance_id,
const std::string& src,
const gfx::Size& size) {
embedder_->NavigateGuest(render_view_host(), instance_id, src, size);
void BrowserPluginEmbedderHelper::OnNavigateGuest(
int instance_id,
const std::string& src,
const BrowserPluginHostMsg_ResizeGuest_Params& resize_params) {
embedder_->NavigateGuest(render_view_host(),
instance_id,
src,
resize_params);
}

void BrowserPluginEmbedderHelper::OnUpdateRectACK(int instance_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class BrowserPluginEmbedderHelper : public RenderViewHostObserver {
// Message handlers.
void OnNavigateGuest(int instance_id,
const std::string& src,
const gfx::Size& size);
const BrowserPluginHostMsg_ResizeGuest_Params& params);
void OnResizeGuest(int instance_id,
const BrowserPluginHostMsg_ResizeGuest_Params& params);
void OnUpdateRectACK(int instance_id, int message_id, const gfx::Size& size);
Expand Down
14 changes: 7 additions & 7 deletions content/browser/browser_plugin/browser_plugin_guest.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,6 @@ class CONTENT_EXPORT BrowserPluginGuest : public WebContentsDelegate,
// WebContentsDelegate implementation.
virtual void RendererUnresponsive(WebContents* source) OVERRIDE;

void SetDamageBuffer(TransportDIB* damage_buffer,
#if defined(OS_WIN)
int damage_buffer_size,
#endif
const gfx::Size& damage_view_size,
float scale_factor);

void UpdateRect(RenderViewHost* render_view_host,
const ViewHostMsg_UpdateRect_Params& params);
void UpdateRectACK(int message_id, const gfx::Size& size);
Expand Down Expand Up @@ -137,6 +130,13 @@ class CONTENT_EXPORT BrowserPluginGuest : public WebContentsDelegate,
virtual void Reload();
// Stop loading the guest.
virtual void Stop();
// Overridden in tests.
virtual void SetDamageBuffer(TransportDIB* damage_buffer,
#if defined(OS_WIN)
int damage_buffer_size,
#endif
const gfx::Size& damage_view_size,
float scale_factor);

private:
friend class TestBrowserPluginGuest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,9 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, NavigateAfterResize) {
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
embedder_web_contents->GetRenderViewHost());

int nxt_width = 100;
int nxt_height = 200;
const gfx::Size nxt_size = gfx::Size(100, 200);
rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
StringPrintf("SetSize(%d, %d);", nxt_width, nxt_height)));
StringPrintf("SetSize(%d, %d);", nxt_size.width(), nxt_size.height())));

rvh->ExecuteJavascriptAndGetValue(string16(), ASCIIToUTF16(
StringPrintf("SetSrc('%s');", kHTMLForGuest)));
Expand All @@ -330,10 +329,9 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, NavigateAfterResize) {
TestBrowserPluginGuest* test_guest = static_cast<TestBrowserPluginGuest*>(
test_guest_web_contents->GetBrowserPluginGuest());


// Wait for the guest to send an UpdateRectMsg, the dimensions should be
// 100 x 200.
test_guest->WaitForUpdateRectMsgWithSize(nxt_width, nxt_height);
// Wait for the guest to receive a damage buffer of size 100x200.
// This means the guest will be painted properly at that size.
test_guest->WaitForDamageBufferWithSize(nxt_size);
}

IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AdvanceFocus) {
Expand Down
Loading

0 comments on commit 92a01cc

Please sign in to comment.