Skip to content

Commit

Permalink
Adds support for capturing a sub rect of the compositing surface.
Browse files Browse the repository at this point in the history
Also removes the old PopulateBitmapWithContents API.

BUG=345865

Review URL: https://codereview.chromium.org/173023005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253898 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
clholgat@chromium.org committed Feb 27, 2014
1 parent 3ab8c11 commit 697b287
Show file tree
Hide file tree
Showing 9 changed files with 24 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package org.chromium.chrome.browser;

import android.graphics.Bitmap;

import org.chromium.content.browser.PageInfo;

/**
Expand All @@ -29,4 +31,14 @@ public interface NativePage extends PageInfo {
* Updates the native page based on the given url.
*/
public void updateForUrl(String url);

/**
* @return An unscaled screenshot of the page.
*/
Bitmap getBitmap();

/**
* @return A screenshot of the page scaled to the specified size.
*/
Bitmap getBitmap(int width, int height);
}
14 changes: 3 additions & 11 deletions content/browser/android/content_view_core_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -699,14 +699,16 @@ void ContentViewCoreImpl::ShowPastePopup(int x_dip, int y_dip) {
void ContentViewCoreImpl::GetScaledContentBitmap(
float scale,
jobject jbitmap_config,
gfx::Rect src_subrect,
const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
if (!view) {
result_callback.Run(false, SkBitmap());
return;
}
SkBitmap::Config skbitmap_format = gfx::ConvertToSkiaConfig(jbitmap_config);
view->GetScaledContentBitmap(scale, skbitmap_format, result_callback);
view->GetScaledContentBitmap(scale, skbitmap_format, src_subrect,
result_callback);
}

void ContentViewCoreImpl::StartContentIntent(const GURL& content_url) {
Expand Down Expand Up @@ -1460,16 +1462,6 @@ jboolean ContentViewCoreImpl::OnAnimate(JNIEnv* env, jobject /* obj */,
return view->Animate(base::TimeTicks::FromInternalValue(frame_time_micros));
}

jboolean ContentViewCoreImpl::PopulateBitmapFromCompositor(JNIEnv* env,
jobject obj,
jobject jbitmap) {
RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
if (!view)
return false;

return view->PopulateBitmapWithContents(jbitmap);
}

void ContentViewCoreImpl::WasResized(JNIEnv* env, jobject obj) {
RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
if (view)
Expand Down
4 changes: 1 addition & 3 deletions content/browser/android/content_view_core_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class ContentViewCoreImpl : public ContentViewCore,
virtual void GetScaledContentBitmap(
float scale,
jobject bitmap_config,
gfx::Rect src_subrect,
const base::Callback<void(bool, const SkBitmap&)>& result_callback)
OVERRIDE;
virtual float GetDpiScale() const OVERRIDE;
Expand Down Expand Up @@ -198,9 +199,6 @@ class ContentViewCoreImpl : public ContentViewCore,
jlong interval_micros);
void OnVSync(JNIEnv* env, jobject /* obj */, jlong frame_time_micros);
jboolean OnAnimate(JNIEnv* env, jobject /* obj */, jlong frame_time_micros);
jboolean PopulateBitmapFromCompositor(JNIEnv* env,
jobject obj,
jobject jbitmap);
void WasResized(JNIEnv* env, jobject obj);
jboolean IsRenderWidgetHostViewReady(JNIEnv* env, jobject obj);
void ExitFullscreen(JNIEnv* env, jobject obj);
Expand Down
40 changes: 5 additions & 35 deletions content/browser/renderer_host/render_widget_host_view_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,18 @@ void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
float scale,
SkBitmap::Config bitmap_config,
gfx::Rect src_subrect,
const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
if (!IsSurfaceAvailableForCopy()) {
result_callback.Run(false, SkBitmap());
return;
}

gfx::Size bounds = layer_->bounds();
gfx::Rect src_subrect(bounds);
if (src_subrect.IsEmpty())
src_subrect = gfx::Rect(bounds);
DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
const gfx::Display& display =
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
float device_scale_factor = display.device_scale_factor();
Expand All @@ -272,40 +276,6 @@ void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
src_subrect, dst_size, result_callback, bitmap_config);
}

bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) {
if (!CompositorImpl::IsInitialized() ||
texture_id_in_layer_ == 0 ||
texture_size_in_layer_.IsEmpty())
return false;

gfx::JavaBitmap bitmap(jbitmap);

// TODO(dtrainor): Eventually add support for multiple formats here.
DCHECK(bitmap.format() == ANDROID_BITMAP_FORMAT_RGBA_8888);

GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();

GLuint texture = helper->CopyAndScaleTexture(
texture_id_in_layer_,
texture_size_in_layer_,
bitmap.size(),
true,
GLHelper::SCALER_QUALITY_FAST);
if (texture == 0u)
return false;

helper->ReadbackTextureSync(texture,
gfx::Rect(bitmap.size()),
static_cast<unsigned char*> (bitmap.pixels()),
SkBitmap::kARGB_8888_Config);

gpu::gles2::GLES2Interface* gl =
ImageTransportFactoryAndroid::GetInstance()->GetContextGL();
gl->DeleteTextures(1, &texture);

return true;
}

bool RenderWidgetHostViewAndroid::HasValidFrame() const {
if (!content_view_core_)
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ class RenderWidgetHostViewAndroid
void GetScaledContentBitmap(
float scale,
SkBitmap::Config bitmap_config,
gfx::Rect src_subrect,
const base::Callback<void(bool, const SkBitmap&)>& result_callback);
bool PopulateBitmapWithContents(jobject jbitmap);

bool HasValidFrame() const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Build;
Expand Down Expand Up @@ -122,21 +121,6 @@ public String getTitle() {
return mContentViewCore.getTitle();
}

@Override
public boolean isReadyForSnapshot() {
return mContentViewCore.isReady();
}

@Override
public Bitmap getBitmap() {
return getBitmap(getWidth(), getHeight());
}

@Override
public Bitmap getBitmap(int width, int height) {
return mContentViewCore.getBitmap(width, height);
}

@Override
public int getBackgroundColor() {
return mContentViewCore.getBackgroundColor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import android.text.Editable;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.ActionMode;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
Expand Down Expand Up @@ -1035,58 +1034,6 @@ public float getContentWidthCss() {
return mRenderCoordinates.getContentWidthCss();
}

public Bitmap getBitmap() {
return getBitmap(getViewportWidthPix(), getViewportHeightPix());
}

public Bitmap getBitmap(int width, int height) {
if (width == 0 || height == 0
|| getViewportWidthPix() == 0 || getViewportHeightPix() == 0) {
return null;
}

Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

if (mNativeContentViewCore != 0 &&
nativePopulateBitmapFromCompositor(mNativeContentViewCore, b)) {
// If we successfully grabbed a bitmap, check if we have to draw the Android overlay
// components as well.
if (mContainerView.getChildCount() > 0) {
Canvas c = new Canvas(b);
c.scale(width / (float) getViewportWidthPix(),
height / (float) getViewportHeightPix());
mContainerView.draw(c);
}
return b;
}

return null;
}

/**
* Generates a bitmap of the content that is performance optimized based on capture time.
*
* <p>
* To have a consistent capture time across devices, we will scale down the captured bitmap
* where necessary to reduce the time to generate the bitmap.
*
* @param width The width of the content to be captured.
* @param height The height of the content to be captured.
* @return A pair of the generated bitmap, and the scale that needs to be applied to return the
* bitmap to it's original size (i.e. if the bitmap is scaled down 50%, this
* will be 2).
*/
public Pair<Bitmap, Float> getScaledPerformanceOptimizedBitmap(int width, int height) {
float scale = 1f;
// On tablets, always scale down to MDPI for performance reasons.
if (DeviceUtils.isTablet(getContext())) {
scale = getContext().getResources().getDisplayMetrics().density;
}
return Pair.create(
getBitmap((int) (width / scale), (int) (height / scale)),
scale);
}

// TODO(teddchoc): Remove all these navigation controller methods from here and have the
// embedders manage it.
/**
Expand Down Expand Up @@ -3444,9 +3391,6 @@ private native void nativeUpdateVSyncParameters(long nativeContentViewCoreImpl,

private native boolean nativeOnAnimate(long nativeContentViewCoreImpl, long frameTimeMicros);

private native boolean nativePopulateBitmapFromCompositor(long nativeContentViewCoreImpl,
Bitmap bitmap);

private native void nativeWasResized(long nativeContentViewCoreImpl);

private native boolean nativeIsRenderWidgetHostViewReady(long nativeContentViewCoreImpl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

package org.chromium.content.browser;

import android.graphics.Bitmap;
import android.view.View;

/**
Expand All @@ -18,21 +17,6 @@ public interface PageInfo {
*/
String getTitle();

/**
* @return True, if the view is in a suitable state for a snapshot.
*/
boolean isReadyForSnapshot();

/**
* @return An unscaled screenshot of the page.
*/
Bitmap getBitmap();

/**
* @return A screenshot of the page scaled to the specified size.
*/
Bitmap getBitmap(int width, int height);

/**
* @return The background color of the page.
*/
Expand Down
2 changes: 2 additions & 0 deletions content/public/browser/android/content_view_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "base/callback.h"
#include "content/common/content_export.h"
#include "content/public/browser/navigation_controller.h"
#include "ui/gfx/rect.h"

class SkBitmap;

Expand Down Expand Up @@ -57,6 +58,7 @@ class CONTENT_EXPORT ContentViewCore {
virtual void GetScaledContentBitmap(
float scale,
jobject bitmap_config,
gfx::Rect src_rect,
const base::Callback<void(bool, const SkBitmap&)>& result_callback) = 0;
virtual float GetDpiScale() const = 0;
virtual void PauseVideo() = 0;
Expand Down

0 comments on commit 697b287

Please sign in to comment.