Chromium Code Reviews| Index: chrome/browser/android/compositor/layer/crushed_sprite_layer.cc |
| diff --git a/chrome/browser/android/compositor/layer/crushed_sprite_layer.cc b/chrome/browser/android/compositor/layer/crushed_sprite_layer.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8d60a18a442115c225c066ae13f76a0fbfec3ef3 |
| --- /dev/null |
| +++ b/chrome/browser/android/compositor/layer/crushed_sprite_layer.cc |
| @@ -0,0 +1,117 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/android/compositor/layer/crushed_sprite_layer.h" |
| + |
| +#include "cc/layers/layer.h" |
| +#include "cc/layers/ui_resource_layer.h" |
| +#include "content/public/browser/android/compositor.h" |
| +#include "ui/android/resources/crushed_sprite_resource.h" |
| +#include "ui/android/resources/resource_manager.h" |
| +#include "ui/gfx/canvas.h" |
| +#include "ui/gfx/skia_util.h" |
| + |
| +namespace chrome { |
| +namespace android { |
| + |
| +// static |
| +scoped_refptr<CrushedSpriteLayer> CrushedSpriteLayer::Create() { |
| + return make_scoped_refptr(new CrushedSpriteLayer()); |
| +} |
| + |
| +scoped_refptr<cc::Layer> CrushedSpriteLayer::layer() { |
| + return layer_; |
| +} |
| + |
| +void CrushedSpriteLayer::DrawSpriteFrame( |
| + ui::ResourceManager* resource_manager, |
| + int bitmap_res_id, |
| + int metadata_res_id, |
| + float completion_percentage) { |
| + DCHECK(completion_percentage >= 0.f && completion_percentage <= 1.f); |
| + |
| + int sprite_frame = completion_percentage * (frame_count_ - 1); |
| + |
| + if (frame_count_ == -1 || sprite_frame != previous_frame_) { |
|
David Trainor- moved to gerrit
2015/10/27 21:00:42
Do we need frame_count_ == -1 if previous_frame wi
Theresa
2015/10/27 21:24:49
Maybe.. if the completion percentage starts at .5
|
| + // Get resource and setup variables. |
| + ui::CrushedSpriteResource* resource = |
| + resource_manager->GetCrushedSpriteResource( |
| + bitmap_res_id, |
| + metadata_res_id); |
| + frame_count_ = resource->GetFrameCount(); |
|
David Trainor- moved to gerrit
2015/10/27 21:00:42
Move up above the other sprite_frame
Theresa
2015/10/27 21:24:49
It's here on purpose. If we're redisplaying the la
|
| + int sprite_frame = completion_percentage * (frame_count_ - 1); |
|
David Trainor- moved to gerrit
2015/10/27 21:00:43
redundant?
Theresa
2015/10/27 21:24:49
If frame_count_ != -1, yes. I'll surround this lin
Theresa
2015/10/28 02:01:53
Done.
|
| + |
| + |
| + // Reset the previous_frame if the animation is being re-run. |
| + if (previous_frame_ > sprite_frame) { |
| + previous_frame_ = 0; |
| + } |
| + |
| + // Set up an SkCanvas backed by an SkBitmap to draw into. |
| + SkBitmap bitmap; |
| + bitmap.allocN32Pixels(resource->GetSpriteSize().width(), |
| + resource->GetSpriteSize().height()); |
| + skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(new SkCanvas(bitmap)); |
| + |
| + // If this isn't the first or last frame, draw the previous frame(s). |
| + // Note(twellington): This assumes that the last frame in the crushed sprite |
| + // animation does not require any previous frames drawn before it. This code |
| + // needs to be updated if crushed sprites are added for which this |
| + // assumption does not hold. |
| + if (sprite_frame != 0 && sprite_frame != resource->GetFrameCount() - 1) { |
| + // Draw the previous frame. |
| + canvas->drawBitmap(previous_frame_bitmap_, 0, 0, nullptr); |
| + |
| + // Draw any skipped frames. |
| + for (int i = previous_frame_ + 1; i < sprite_frame; ++i) { |
| + DrawRectanglesForFrame(resource, i, canvas); |
| + } |
| + } |
| + |
| + // Draw the current frame. |
| + DrawRectanglesForFrame(resource, sprite_frame, canvas); |
| + |
| + // Set the bitmap on layer_. |
| + bitmap.setImmutable(); |
| + layer_->SetBitmap(bitmap); |
| + |
| + // Evict the crushed sprite bitmap from memory if this is the last frame. |
| + if (sprite_frame == frame_count_ - 1) { |
| + resource->GetBitmap().empty(); |
|
David Trainor- moved to gerrit
2015/10/27 21:00:42
Doesn't this just return if it's empty? Also do w
Theresa
2015/10/27 21:24:49
Discussed offline, I'll use .reset() and add a met
Theresa
2015/10/28 02:01:53
Done.
|
| + } |
| + |
| + // Update previous_frame_* variables. |
| + previous_frame_bitmap_ = bitmap; |
| + previous_frame_ = sprite_frame; |
| + } |
| +} |
| + |
| +void CrushedSpriteLayer::DrawRectanglesForFrame( |
| + ui::CrushedSpriteResource* resource, |
| + int frame, |
| + skia::RefPtr<SkCanvas> canvas) { |
| + ui::CrushedSpriteResource::FrameSrcDstRects src_dst_rects = |
| + resource->GetRectanglesForFrame(frame); |
| + for (const auto& rect : src_dst_rects) { |
| + canvas->drawBitmapRect(resource->GetBitmap(), |
| + gfx::RectToSkRect(rect.first), |
| + gfx::RectToSkRect(rect.second), |
| + nullptr); |
| + } |
| +} |
| + |
| +CrushedSpriteLayer::CrushedSpriteLayer() |
| + : layer_( |
| + cc::UIResourceLayer::Create(content::Compositor::LayerSettings())), |
| + frame_count_(-1), |
| + previous_frame_(-1) { |
| + layer_->SetIsDrawable(true); |
| +} |
| + |
| + |
| +CrushedSpriteLayer::~CrushedSpriteLayer() { |
| +} |
| + |
| +} // namespace android |
| +} // namespace chrome |