Skip to content

Commit

Permalink
Make the AwPixelInfo more skia version independent
Browse files Browse the repository at this point in the history
Previously the config and clip_region field formats depended on skia
internal implementation details. This patch decouples the interface
from the specific skia version in use.


BUG=

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216841 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
joth@chromium.org committed Aug 10, 2013
1 parent 26f4aa4 commit 5114048
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 40 deletions.
106 changes: 74 additions & 32 deletions android_webview/browser/in_process_view_renderer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@ bool RenderPictureToCanvas(SkPicture* picture, SkCanvas* canvas) {
return true;
}

class ScopedPixelAccess {
public:
ScopedPixelAccess(JNIEnv* env, jobject java_canvas) {
AwDrawSWFunctionTable* sw_functions =
BrowserViewRenderer::GetAwDrawSWFunctionTable();
pixels_ = sw_functions ?
sw_functions->access_pixels(env, java_canvas) : NULL;
}
~ScopedPixelAccess() {
if (pixels_)
BrowserViewRenderer::GetAwDrawSWFunctionTable()->release_pixels(pixels_);
}
AwPixelInfo* pixels() { return pixels_; }

private:
AwPixelInfo* pixels_;

DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPixelAccess);
};

bool HardwareEnabled() {
static bool g_hw_enabled = !CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableWebViewGLMode);
Expand Down Expand Up @@ -413,12 +433,32 @@ bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded(
void* owner_key) {
TRACE_EVENT0("android_webview",
"InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded");

JNIEnv* env = AttachCurrentThread();
ScopedPixelAccess auto_release_pixels(env, java_canvas);
AwPixelInfo* pixels = auto_release_pixels.pixels();
SkMatrix matrix;
SkBitmap::Config config(SkBitmap::kNo_Config);
if (pixels) {
switch (pixels->config) {
case AwConfig_ARGB_8888:
config = SkBitmap::kARGB_8888_Config;
break;
case AwConfig_RGB_565:
config = SkBitmap::kRGB_565_Config;
break;
}

AwDrawSWFunctionTable* sw_functions = GetAwDrawSWFunctionTable();
AwPixelInfo* pixels = sw_functions ?
sw_functions->access_pixels(env, java_canvas) : NULL;
if (pixels == NULL) {
for (int i = 0; i < 9; i++) {
matrix.set(i, pixels->matrix[i]);
}
// Workaround for http://crbug.com/271096: SW draw only supports
// translate & scale transforms.
if (matrix.getType() & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))
config = SkBitmap::kNo_Config;
}

if (config == SkBitmap::kNo_Config) {
// Render into an auxiliary bitmap if pixel info is not available.
ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas);
TRACE_EVENT0("android_webview", "RenderToAuxBitmap");
Expand Down Expand Up @@ -447,41 +487,43 @@ bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded(
}

// Draw in a SkCanvas built over the pixel information.
bool succeeded = false;
{
SkBitmap bitmap;
bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config),
pixels->width,
pixels->height,
pixels->row_bytes);
bitmap.setPixels(pixels->pixels);
SkDevice device(bitmap);
SkCanvas canvas(&device);
SkMatrix matrix;
for (int i = 0; i < 9; i++)
matrix.set(i, pixels->matrix[i]);
canvas.setMatrix(matrix);

if (pixels->clip_region_size) {
SkRegion clip_region;
size_t bytes_read = clip_region.readFromMemory(pixels->clip_region);
DCHECK_EQ(pixels->clip_region_size, bytes_read);
canvas.setClipRegion(clip_region);
} else {
canvas.clipRect(gfx::RectToSkRect(clip));
SkBitmap bitmap;
bitmap.setConfig(config,
pixels->width,
pixels->height,
pixels->row_bytes);
bitmap.setPixels(pixels->pixels);
SkDevice device(bitmap);
SkCanvas canvas(&device);
canvas.setMatrix(matrix);

if (pixels->clip_region) {
SkRegion clip_region;
size_t bytes_read = clip_region.readFromMemory(pixels->clip_region);
DCHECK_EQ(pixels->clip_region_size, bytes_read);
canvas.setClipRegion(clip_region);
} else if (pixels->clip_rect_count) {
SkRegion clip;
for (int i = 0; i < pixels->clip_rect_count; ++i) {
clip.op(SkIRect::MakeXYWH(pixels->clip_rects[i + 0],
pixels->clip_rects[i + 1],
pixels->clip_rects[i + 2],
pixels->clip_rects[i + 3]),
SkRegion::kUnion_Op);
}
canvas.translate(scroll_correction.x(),
scroll_correction.y());

succeeded = render_source.Run(&canvas);
canvas.setClipRegion(clip);
}

sw_functions->release_pixels(pixels);
return succeeded;
canvas.translate(scroll_correction.x(),
scroll_correction.y());

return render_source.Run(&canvas);
}

skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width,
int height) {
TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture");

// Return empty Picture objects for empty SkPictures.
skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture);
if (width <= 0 || height <= 0) {
Expand Down
30 changes: 22 additions & 8 deletions android_webview/public/browser/draw_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,30 @@

class SkPicture;

static const int kAwPixelInfoVersion = 2;

// Values of the AwPixelInfo::config field.
enum AwPixelConfig {
AwConfig_RGB_565 = 4,
AwConfig_ARGB_4444 = 5,
AwConfig_ARGB_8888 = 6,
};

// Holds the information required to implement the SW draw to system canvas.
struct AwPixelInfo {
int config; // In SkBitmap::Config format.
int width; // In pixels.
int height; // In pixels.
int row_bytes; // Number of bytes from start of one line to next.
void* pixels; // The pixels, all (height * row_bytes) of them.
float matrix[9]; // The matrix currently in effect on the canvas.
void* clip_region; // Flattened clip region.
size_t clip_region_size; // Number of bytes in |clip_region|.
int version; // The kAwPixelInfoVersion this struct was built with.
int config; // |pixel| format: a value from AwPixelConfig.
int width; // In pixels.
int height; // In pixels.
int row_bytes; // Number of bytes from start of one line to next.
void* pixels; // The pixels, all (height * row_bytes) of them.
// The Matrix and Clip are relative to |pixels|, not the source canvas.
float matrix[9]; // The matrix currently in effect on the canvas.
int clip_rect_count; // Number of rects in |clip_rects|.
int* clip_rects; // Clip area: 4 ints per rect in {x,y,w,h} format.
void* clip_region; // TODO(joth): remove clip_region and clip_region_size.
size_t clip_region_size;
// NOTE: If you add more members, bump kAwPixelInfoVersion.
};

// Function that can be called to fish out the underlying native pixel data
Expand Down

0 comments on commit 5114048

Please sign in to comment.