 Chromium Code Reviews
 Chromium Code Reviews Issue 1337703002:
  [Contextual Search] Add support for crushed sprites and animate the search provider icon  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1337703002:
  [Contextual Search] Add support for crushed sprites and animate the search provider icon  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| 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 |