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..704d88148e86117a7bfc66adddc8ca25c7a03ac2 |
--- /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( |
+ ui::ResourceManager* resource_manager) { |
+ return make_scoped_refptr(new CrushedSpriteLayer(resource_manager)); |
+} |
+ |
+scoped_refptr<cc::Layer> CrushedSpriteLayer::layer() { |
+ return layer_; |
+} |
+ |
+void CrushedSpriteLayer::SetCrushedSpriteResource( |
+ scoped_refptr<ui::CrushedSpriteResource> resource) { |
+ resource_ = resource; |
David Trainor- moved to gerrit
2015/10/15 21:04:57
Ideally we wouldn't hold onto the resource here.
Theresa
2015/10/24 00:06:45
I got rid of this method and just pass the resourc
|
+} |
+ |
+void CrushedSpriteLayer::DrawSpriteFrame(int sprite_frame) { |
David Trainor- moved to gerrit
2015/10/15 21:04:57
Should you clamp sprite_frame between 0 and the ma
Theresa
2015/10/24 00:06:45
Done.
|
+ if (sprite_frame == 0 || sprite_frame != previous_frame_) { |
+ // Reset the previous_frame if the animation is being re-run. |
+ if (previous_frame_ > sprite_frame) { |
+ previous_frame_ = 0; |
+ } |
+ |
+ // If this is the last frame and a bitmap for it has been cached with the |
+ // resource, set the bitmap on layer_ and return. |
+ if (sprite_frame == resource_->GetFrameCount() - 1 && |
+ !resource_->GetBitmapForLastFrame().empty()) { |
David Trainor- moved to gerrit
2015/10/15 21:04:57
Do we need this? Can't we rely on the sprite_fram
Theresa
2015/10/24 00:06:44
I think you mean rely on previous_frame_bitmap to
David Trainor- moved to gerrit
2015/10/27 15:14:47
I see your point. I'd be okay with sharing it. S
Theresa
2015/10/27 19:48:02
Done.
|
+ layer_->SetBitmap(resource_->GetBitmapForLastFrame()); |
+ return; |
+ } |
+ |
+ // Reload the source bitmap if necessary. |
+ if (resource_->BitmapHasBeenEvictedFromMemory()) { |
David Trainor- moved to gerrit
2015/10/15 21:04:57
See above. Can probably simplify this a lot and r
Theresa
2015/10/24 00:06:45
I put the logic for evicting the sprite sheet from
David Trainor- moved to gerrit
2015/10/27 15:14:47
Won't this cause reloads during animations if two
Theresa
2015/10/27 19:48:02
As discussed offline, yes, it could cause unnecess
|
+ resource_manager_->ReloadCrushedSpriteResource( |
+ resource_->GetBitmapResourceId()); |
+ } |
+ |
+ // Set up an SkCanvas backed by an SkBitmap to draw into. |
+ SkBitmap* bitmap = new SkBitmap(); |
+ bitmap->allocN32Pixels(resource_->GetSpriteSize(), |
+ resource_->GetSpriteSize()); |
+ SkCanvas* canvas = new SkCanvas(*bitmap); |
David Trainor- moved to gerrit
2015/10/15 21:04:57
Leaking canvas and bitmap. Use:
// Don't worry,
Theresa
2015/10/24 00:06:44
Done.
|
+ |
+ // 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); |
David Trainor- moved to gerrit
2015/10/15 21:04:57
So... UIResourceBitmap expects an immututable bitm
Theresa
2015/10/24 00:06:45
I'm not sure why it has to be immutable (it just h
David Trainor- moved to gerrit
2015/10/27 15:14:47
I'm not sure if he still works here. I would imag
Theresa
2015/10/27 19:48:02
Acknowledged.
|
+ |
+ // Draw any skipped frames. |
+ for (int i = previous_frame_ + 1; i < sprite_frame; ++i) { |
+ DrawRectanglesForFrame(i, canvas); |
+ } |
+ } |
+ |
+ // Draw the current frame. |
+ DrawRectanglesForFrame(sprite_frame, canvas); |
+ |
+ // Set the bitmap on layer_. |
+ bitmap->setImmutable(); |
+ layer_->SetBitmap(*bitmap); |
+ |
+ // Cache the bitmap on the resource if this is the last frame. |
+ if (sprite_frame == resource_->GetFrameCount() - 1) { |
David Trainor- moved to gerrit
2015/10/15 21:04:57
See above, probably don't need.
Theresa
2015/10/27 19:48:02
I left the bitmap memory ejection here but moved t
|
+ resource_->SetBitmapForLastFrame(*bitmap); |
+ } |
+ |
+ // Update previous_frame_* variables. |
+ previous_frame_bitmap_ = *bitmap; |
+ previous_frame_ = sprite_frame; |
+ } |
+} |
+ |
+void CrushedSpriteLayer::DrawRectanglesForFrame(int frame, SkCanvas* canvas) { |
David Trainor- moved to gerrit
2015/10/15 21:04:57
skia::RefPtr<SkCanvas>
Theresa
2015/10/24 00:06:45
Done.
|
+ ui::CrushedSpriteResource::FrameSrcDstRects src_dst_rects = |
+ resource_->GetRectanglesForFrame(frame); |
+ for (auto rect : src_dst_rects) { |
David Trainor- moved to gerrit
2015/10/15 21:04:57
auto& so we don't copy the object?
Theresa
2015/10/24 00:06:44
Done.
|
+ canvas->drawBitmapRect(resource_->GetBitmap(), |
+ gfx::RectToSkRect(rect.first), |
+ gfx::RectToSkRect(rect.second), |
+ nullptr); |
+ } |
+} |
+ |
+CrushedSpriteLayer::CrushedSpriteLayer(ui::ResourceManager* resource_manager) |
+ : resource_manager_(resource_manager), |
+ layer_( |
+ cc::UIResourceLayer::Create(content::Compositor::LayerSettings())), |
+ previous_frame_(0) { |
David Trainor- moved to gerrit
2015/10/15 21:04:57
-1 to say that we haven't drawn the first frame?
Theresa
2015/10/24 00:06:44
Done.
|
+ layer_->SetIsDrawable(true); |
+} |
+ |
+ |
+CrushedSpriteLayer::~CrushedSpriteLayer() { |
+} |
+ |
+} // namespace android |
+} // namespace chrome |