Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: cc/trees/layer_tree_host_unittest.cc

Issue 99253004: cc: Allow copy requests to provide a texture. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: mailbox: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/trees/layer_tree_host.h" 5 #include "cc/trees/layer_tree_host.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
(...skipping 2909 matching lines...) Expand 10 before | Expand all | Expand 10 after
2920 2920
2921 int io_surface_id_; 2921 int io_surface_id_;
2922 MockIOSurfaceWebGraphicsContext3D* mock_context_; 2922 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2923 gfx::Size io_surface_size_; 2923 gfx::Size io_surface_size_;
2924 }; 2924 };
2925 2925
2926 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335 2926 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
2927 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( 2927 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2928 LayerTreeHostTestIOSurfaceDrawing); 2928 LayerTreeHostTestIOSurfaceDrawing);
2929 2929
2930 class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
2931 protected:
2932 virtual void SetupTree() OVERRIDE {
2933 root = FakeContentLayer::Create(&client_);
2934 root->SetBounds(gfx::Size(20, 20));
2935
2936 child = FakeContentLayer::Create(&client_);
2937 child->SetBounds(gfx::Size(10, 10));
2938 root->AddChild(child);
2939
2940 layer_tree_host()->SetRootLayer(root);
2941 LayerTreeHostTest::SetupTree();
2942 }
2943
2944 virtual void BeginTest() OVERRIDE {
2945 PostSetNeedsCommitToMainThread();
2946 }
2947
2948 virtual void DidCommitAndDrawFrame() OVERRIDE {
2949 WaitForCallback();
2950 }
2951
2952 void WaitForCallback() {
2953 base::MessageLoop::current()->PostTask(
2954 FROM_HERE,
2955 base::Bind(
2956 &LayerTreeHostTestAsyncReadback::NextStep,
2957 base::Unretained(this)));
2958 }
2959
2960 void NextStep() {
2961 int frame = layer_tree_host()->source_frame_number();
2962 switch (frame) {
2963 case 1:
2964 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2965 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2966 base::Unretained(this))));
2967 EXPECT_EQ(0u, callbacks_.size());
2968 break;
2969 case 2:
2970 if (callbacks_.size() < 1u) {
2971 WaitForCallback();
2972 return;
2973 }
2974 EXPECT_EQ(1u, callbacks_.size());
2975 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
2976
2977 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2978 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2979 base::Unretained(this))));
2980 root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2981 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2982 base::Unretained(this))));
2983 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2984 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2985 base::Unretained(this))));
2986 EXPECT_EQ(1u, callbacks_.size());
2987 break;
2988 case 3:
2989 if (callbacks_.size() < 4u) {
2990 WaitForCallback();
2991 return;
2992 }
2993 EXPECT_EQ(4u, callbacks_.size());
2994 // The child was copied to a bitmap and passed back twice.
2995 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
2996 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
2997 // The root was copied to a bitmap and passed back also.
2998 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
2999 EndTest();
3000 break;
3001 }
3002 }
3003
3004 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3005 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3006 EXPECT_TRUE(result->HasBitmap());
3007 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
3008 EXPECT_EQ(result->size().ToString(),
3009 gfx::Size(bitmap->width(), bitmap->height()).ToString());
3010 callbacks_.push_back(result->size());
3011 }
3012
3013 virtual void AfterTest() OVERRIDE {
3014 EXPECT_EQ(4u, callbacks_.size());
3015 }
3016
3017 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3018 OVERRIDE {
3019 scoped_ptr<FakeOutputSurface> output_surface;
3020 if (use_gl_renderer_) {
3021 output_surface = FakeOutputSurface::Create3d().Pass();
3022 } else {
3023 output_surface = FakeOutputSurface::CreateSoftware(
3024 make_scoped_ptr(new SoftwareOutputDevice)).Pass();
3025 }
3026 return output_surface.PassAs<OutputSurface>();
3027 }
3028
3029 bool use_gl_renderer_;
3030 std::vector<gfx::Size> callbacks_;
3031 FakeContentLayerClient client_;
3032 scoped_refptr<FakeContentLayer> root;
3033 scoped_refptr<FakeContentLayer> child;
3034 };
3035
3036 // Readback can't be done with a delegating renderer.
3037 TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
3038 use_gl_renderer_ = true;
3039 RunTest(false, false, false);
3040 }
3041
3042 TEST_F(LayerTreeHostTestAsyncReadback,
3043 GLRenderer_RunMultiThread_MainThreadPainting) {
3044 use_gl_renderer_ = true;
3045 RunTest(true, false, false);
3046 }
3047
3048 TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
3049 use_gl_renderer_ = false;
3050 RunTest(false, false, false);
3051 }
3052
3053 TEST_F(LayerTreeHostTestAsyncReadback,
3054 SoftwareRenderer_RunMultiThread_MainThreadPainting) {
3055 use_gl_renderer_ = false;
3056 RunTest(true, false, false);
3057 }
3058
3059 class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
3060 protected:
3061 virtual void SetupTree() OVERRIDE {
3062 root_ = FakeContentLayer::Create(&client_);
3063 root_->SetBounds(gfx::Size(20, 20));
3064
3065 main_destroyed_ = FakeContentLayer::Create(&client_);
3066 main_destroyed_->SetBounds(gfx::Size(15, 15));
3067 root_->AddChild(main_destroyed_);
3068
3069 impl_destroyed_ = FakeContentLayer::Create(&client_);
3070 impl_destroyed_->SetBounds(gfx::Size(10, 10));
3071 root_->AddChild(impl_destroyed_);
3072
3073 layer_tree_host()->SetRootLayer(root_);
3074 LayerTreeHostTest::SetupTree();
3075 }
3076
3077 virtual void BeginTest() OVERRIDE {
3078 callback_count_ = 0;
3079 PostSetNeedsCommitToMainThread();
3080 }
3081
3082 virtual void DidCommit() OVERRIDE {
3083 int frame = layer_tree_host()->source_frame_number();
3084 switch (frame) {
3085 case 1:
3086 main_destroyed_->RequestCopyOfOutput(
3087 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3088 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
3089 CopyOutputCallback,
3090 base::Unretained(this))));
3091 impl_destroyed_->RequestCopyOfOutput(
3092 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3093 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
3094 CopyOutputCallback,
3095 base::Unretained(this))));
3096 EXPECT_EQ(0, callback_count_);
3097
3098 // Destroy the main thread layer right away.
3099 main_destroyed_->RemoveFromParent();
3100 main_destroyed_ = NULL;
3101
3102 // Should callback with a NULL bitmap.
3103 EXPECT_EQ(1, callback_count_);
3104
3105 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
3106 layer_tree_host()->SetViewportSize(gfx::Size());
3107 break;
3108 case 2:
3109 // Flush the message loops and make sure the callbacks run.
3110 layer_tree_host()->SetNeedsCommit();
3111 break;
3112 case 3:
3113 // No drawing means no readback yet.
3114 EXPECT_EQ(1, callback_count_);
3115
3116 // Destroy the impl thread layer.
3117 impl_destroyed_->RemoveFromParent();
3118 impl_destroyed_ = NULL;
3119
3120 // No callback yet because it's on the impl side.
3121 EXPECT_EQ(1, callback_count_);
3122 break;
3123 case 4:
3124 // Flush the message loops and make sure the callbacks run.
3125 layer_tree_host()->SetNeedsCommit();
3126 break;
3127 case 5:
3128 // We should get another callback with a NULL bitmap.
3129 EXPECT_EQ(2, callback_count_);
3130 EndTest();
3131 break;
3132 }
3133 }
3134
3135 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3136 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3137 EXPECT_TRUE(result->IsEmpty());
3138 ++callback_count_;
3139 }
3140
3141 virtual void AfterTest() OVERRIDE {}
3142
3143 int callback_count_;
3144 FakeContentLayerClient client_;
3145 scoped_refptr<FakeContentLayer> root_;
3146 scoped_refptr<FakeContentLayer> main_destroyed_;
3147 scoped_refptr<FakeContentLayer> impl_destroyed_;
3148 };
3149
3150 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed);
3151
3152 class LayerTreeHostTestAsyncReadbackInHiddenSubtree : public LayerTreeHostTest {
3153 protected:
3154 virtual void SetupTree() OVERRIDE {
3155 root_ = FakeContentLayer::Create(&client_);
3156 root_->SetBounds(gfx::Size(20, 20));
3157
3158 grand_parent_layer_ = FakeContentLayer::Create(&client_);
3159 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
3160 root_->AddChild(grand_parent_layer_);
3161
3162 // parent_layer_ owns a render surface.
3163 parent_layer_ = FakeContentLayer::Create(&client_);
3164 parent_layer_->SetBounds(gfx::Size(15, 15));
3165 parent_layer_->SetForceRenderSurface(true);
3166 grand_parent_layer_->AddChild(parent_layer_);
3167
3168 copy_layer_ = FakeContentLayer::Create(&client_);
3169 copy_layer_->SetBounds(gfx::Size(10, 10));
3170 parent_layer_->AddChild(copy_layer_);
3171
3172 layer_tree_host()->SetRootLayer(root_);
3173 LayerTreeHostTest::SetupTree();
3174 }
3175
3176 void AddCopyRequest(Layer* layer) {
3177 layer->RequestCopyOfOutput(
3178 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3179 &LayerTreeHostTestAsyncReadbackInHiddenSubtree::CopyOutputCallback,
3180 base::Unretained(this))));
3181 }
3182
3183 virtual void BeginTest() OVERRIDE {
3184 callback_count_ = 0;
3185 PostSetNeedsCommitToMainThread();
3186
3187 AddCopyRequest(copy_layer_.get());
3188 }
3189
3190 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3191 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3192 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3193 ++callback_count_;
3194
3195 switch (callback_count_) {
3196 case 1:
3197 // Hide the copy request layer.
3198 grand_parent_layer_->SetHideLayerAndSubtree(false);
3199 parent_layer_->SetHideLayerAndSubtree(false);
3200 copy_layer_->SetHideLayerAndSubtree(true);
3201 AddCopyRequest(copy_layer_.get());
3202 break;
3203 case 2:
3204 // Hide the copy request layer's parent only.
3205 grand_parent_layer_->SetHideLayerAndSubtree(false);
3206 parent_layer_->SetHideLayerAndSubtree(true);
3207 copy_layer_->SetHideLayerAndSubtree(false);
3208 AddCopyRequest(copy_layer_.get());
3209 break;
3210 case 3:
3211 // Hide the copy request layer's grand parent only.
3212 grand_parent_layer_->SetHideLayerAndSubtree(true);
3213 parent_layer_->SetHideLayerAndSubtree(false);
3214 copy_layer_->SetHideLayerAndSubtree(false);
3215 AddCopyRequest(copy_layer_.get());
3216 break;
3217 case 4:
3218 // Hide the copy request layer's parent and grandparent.
3219 grand_parent_layer_->SetHideLayerAndSubtree(true);
3220 parent_layer_->SetHideLayerAndSubtree(true);
3221 copy_layer_->SetHideLayerAndSubtree(false);
3222 AddCopyRequest(copy_layer_.get());
3223 break;
3224 case 5:
3225 // Hide the copy request layer as well as its parent and grandparent.
3226 grand_parent_layer_->SetHideLayerAndSubtree(true);
3227 parent_layer_->SetHideLayerAndSubtree(true);
3228 copy_layer_->SetHideLayerAndSubtree(true);
3229 AddCopyRequest(copy_layer_.get());
3230 break;
3231 case 6:
3232 EndTest();
3233 break;
3234 }
3235 }
3236
3237 virtual void AfterTest() OVERRIDE {}
3238
3239 int callback_count_;
3240 FakeContentLayerClient client_;
3241 scoped_refptr<FakeContentLayer> root_;
3242 scoped_refptr<FakeContentLayer> grand_parent_layer_;
3243 scoped_refptr<FakeContentLayer> parent_layer_;
3244 scoped_refptr<FakeContentLayer> copy_layer_;
3245 };
3246
3247 // No output to copy for delegated renderers.
3248 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3249 LayerTreeHostTestAsyncReadbackInHiddenSubtree);
3250
3251 class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
3252 : public LayerTreeHostTest {
3253 protected:
3254 virtual void SetupTree() OVERRIDE {
3255 root_ = FakeContentLayer::Create(&client_);
3256 root_->SetBounds(gfx::Size(20, 20));
3257
3258 grand_parent_layer_ = FakeContentLayer::Create(&client_);
3259 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
3260 grand_parent_layer_->SetHideLayerAndSubtree(true);
3261 root_->AddChild(grand_parent_layer_);
3262
3263 // parent_layer_ owns a render surface.
3264 parent_layer_ = FakeContentLayer::Create(&client_);
3265 parent_layer_->SetBounds(gfx::Size(15, 15));
3266 parent_layer_->SetForceRenderSurface(true);
3267 grand_parent_layer_->AddChild(parent_layer_);
3268
3269 copy_layer_ = FakeContentLayer::Create(&client_);
3270 copy_layer_->SetBounds(gfx::Size(10, 10));
3271 parent_layer_->AddChild(copy_layer_);
3272
3273 layer_tree_host()->SetRootLayer(root_);
3274 LayerTreeHostTest::SetupTree();
3275 }
3276
3277 virtual void BeginTest() OVERRIDE {
3278 did_draw_ = false;
3279 PostSetNeedsCommitToMainThread();
3280
3281 copy_layer_->RequestCopyOfOutput(
3282 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3283 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
3284 CopyOutputCallback,
3285 base::Unretained(this))));
3286 }
3287
3288 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3289 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3290 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3291 EndTest();
3292 }
3293
3294 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3295 Renderer* renderer = host_impl->renderer();
3296
3297 LayerImpl* root = host_impl->active_tree()->root_layer();
3298 LayerImpl* grand_parent = root->children()[0];
3299 LayerImpl* parent = grand_parent->children()[0];
3300 LayerImpl* copy_layer = parent->children()[0];
3301
3302 // |parent| owns a surface, but it was hidden and not part of the copy
3303 // request so it should not allocate any resource.
3304 EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
3305 parent->render_surface()->RenderPassId()));
3306
3307 // |copy_layer| should have been rendered to a texture since it was needed
3308 // for a copy request.
3309 EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
3310 copy_layer->render_surface()->RenderPassId()));
3311
3312 did_draw_ = true;
3313 }
3314
3315 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
3316
3317 FakeContentLayerClient client_;
3318 bool did_draw_;
3319 scoped_refptr<FakeContentLayer> root_;
3320 scoped_refptr<FakeContentLayer> grand_parent_layer_;
3321 scoped_refptr<FakeContentLayer> parent_layer_;
3322 scoped_refptr<FakeContentLayer> copy_layer_;
3323 };
3324
3325 // No output to copy for delegated renderers.
3326 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3327 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
3328
3329 class LayerTreeHostTestAsyncReadbackClippedOut : public LayerTreeHostTest {
3330 protected:
3331 virtual void SetupTree() OVERRIDE {
3332 root_ = FakeContentLayer::Create(&client_);
3333 root_->SetBounds(gfx::Size(20, 20));
3334
3335 parent_layer_ = FakeContentLayer::Create(&client_);
3336 parent_layer_->SetBounds(gfx::Size(15, 15));
3337 parent_layer_->SetMasksToBounds(true);
3338 root_->AddChild(parent_layer_);
3339
3340 copy_layer_ = FakeContentLayer::Create(&client_);
3341 copy_layer_->SetPosition(gfx::Point(15, 15));
3342 copy_layer_->SetBounds(gfx::Size(10, 10));
3343 parent_layer_->AddChild(copy_layer_);
3344
3345 layer_tree_host()->SetRootLayer(root_);
3346 LayerTreeHostTest::SetupTree();
3347 }
3348
3349 virtual void BeginTest() OVERRIDE {
3350 PostSetNeedsCommitToMainThread();
3351
3352 copy_layer_->RequestCopyOfOutput(
3353 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3354 &LayerTreeHostTestAsyncReadbackClippedOut::CopyOutputCallback,
3355 base::Unretained(this))));
3356 }
3357
3358 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3359 // We should still get a callback with no output if the copy requested layer
3360 // was completely clipped away.
3361 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3362 EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
3363 EndTest();
3364 }
3365
3366 virtual void AfterTest() OVERRIDE {}
3367
3368 FakeContentLayerClient client_;
3369 scoped_refptr<FakeContentLayer> root_;
3370 scoped_refptr<FakeContentLayer> parent_layer_;
3371 scoped_refptr<FakeContentLayer> copy_layer_;
3372 };
3373
3374 // No output to copy for delegated renderers.
3375 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3376 LayerTreeHostTestAsyncReadbackClippedOut);
3377
3378 class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostTest {
3379 protected:
3380 virtual void SetupTree() OVERRIDE {
3381 root_ = FakeContentLayer::Create(&client_);
3382 root_->SetBounds(gfx::Size(20, 20));
3383
3384 copy_layer_ = FakeContentLayer::Create(&client_);
3385 copy_layer_->SetBounds(gfx::Size(10, 10));
3386 root_->AddChild(copy_layer_);
3387
3388 layer_tree_host()->SetRootLayer(root_);
3389 LayerTreeHostTest::SetupTree();
3390 }
3391
3392 void AddCopyRequest(Layer* layer) {
3393 layer->RequestCopyOfOutput(
3394 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3395 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
3396 base::Unretained(this))));
3397 }
3398
3399 virtual void BeginTest() OVERRIDE {
3400 saw_copy_request_ = false;
3401 callback_count_ = 0;
3402 PostSetNeedsCommitToMainThread();
3403
3404 // Prevent drawing.
3405 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
3406
3407 AddCopyRequest(copy_layer_.get());
3408 }
3409
3410 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3411 if (impl->active_tree()->source_frame_number() == 0) {
3412 LayerImpl* root = impl->active_tree()->root_layer();
3413 EXPECT_TRUE(root->children()[0]->HasCopyRequest());
3414 saw_copy_request_ = true;
3415 }
3416 }
3417
3418 virtual void DidCommit() OVERRIDE {
3419 if (layer_tree_host()->source_frame_number() == 1) {
3420 // Allow drawing.
3421 layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
3422
3423 AddCopyRequest(copy_layer_.get());
3424 }
3425 }
3426
3427 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3428 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3429 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3430 ++callback_count_;
3431
3432 if (callback_count_ == 2)
3433 EndTest();
3434 }
3435
3436 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
3437
3438 bool saw_copy_request_;
3439 int callback_count_;
3440 FakeContentLayerClient client_;
3441 scoped_refptr<FakeContentLayer> root_;
3442 scoped_refptr<FakeContentLayer> copy_layer_;
3443 };
3444
3445 // No output to copy for delegated renderers.
3446 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3447 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
3448
3449 class LayerTreeHostTestAsyncReadbackLostOutputSurface
3450 : public LayerTreeHostTest {
3451 protected:
3452 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3453 OVERRIDE {
3454 if (!first_context_provider_.get()) {
3455 first_context_provider_ = TestContextProvider::Create();
3456 return FakeOutputSurface::Create3d(first_context_provider_)
3457 .PassAs<OutputSurface>();
3458 }
3459
3460 EXPECT_FALSE(second_context_provider_.get());
3461 second_context_provider_ = TestContextProvider::Create();
3462 return FakeOutputSurface::Create3d(second_context_provider_)
3463 .PassAs<OutputSurface>();
3464 }
3465
3466 virtual void SetupTree() OVERRIDE {
3467 root_ = FakeContentLayer::Create(&client_);
3468 root_->SetBounds(gfx::Size(20, 20));
3469
3470 copy_layer_ = FakeContentLayer::Create(&client_);
3471 copy_layer_->SetBounds(gfx::Size(10, 10));
3472 root_->AddChild(copy_layer_);
3473
3474 layer_tree_host()->SetRootLayer(root_);
3475 LayerTreeHostTest::SetupTree();
3476 }
3477
3478 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3479
3480 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3481 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3482 EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString());
3483 EXPECT_TRUE(result->HasTexture());
3484
3485 // Save the result for later.
3486 EXPECT_FALSE(result_);
3487 result_ = result.Pass();
3488
3489 // Post a commit to lose the output surface.
3490 layer_tree_host()->SetNeedsCommit();
3491 }
3492
3493 virtual void DidCommitAndDrawFrame() OVERRIDE {
3494 switch (layer_tree_host()->source_frame_number()) {
3495 case 1:
3496 // The layers have been pushed to the impl side. The layer textures have
3497 // been allocated.
3498
3499 // Request a copy of the layer. This will use another texture.
3500 copy_layer_->RequestCopyOfOutput(
3501 CopyOutputRequest::CreateRequest(base::Bind(
3502 &LayerTreeHostTestAsyncReadbackLostOutputSurface::
3503 CopyOutputCallback,
3504 base::Unretained(this))));
3505 break;
3506 case 4:
3507 // With SingleThreadProxy it takes two commits to finally swap after a
3508 // context loss.
3509 case 5:
3510 // Now destroy the CopyOutputResult, releasing the texture inside back
3511 // to the compositor.
3512 EXPECT_TRUE(result_);
3513 result_.reset();
3514
3515 // Check that it is released.
3516 ImplThreadTaskRunner()->PostTask(
3517 FROM_HERE,
3518 base::Bind(&LayerTreeHostTestAsyncReadbackLostOutputSurface::
3519 CheckNumTextures,
3520 base::Unretained(this),
3521 num_textures_after_loss_ - 1));
3522 break;
3523 }
3524 }
3525
3526 virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result)
3527 OVERRIDE {
3528 switch (impl->active_tree()->source_frame_number()) {
3529 case 0:
3530 // The layers have been drawn, so their textures have been allocated.
3531 EXPECT_FALSE(result_);
3532 num_textures_without_readback_ =
3533 first_context_provider_->TestContext3d()->NumTextures();
3534 break;
3535 case 1:
3536 // We did a readback, so there will be a readback texture around now.
3537 EXPECT_LT(num_textures_without_readback_,
3538 first_context_provider_->TestContext3d()->NumTextures());
3539 break;
3540 case 2:
3541 // The readback texture is collected.
3542 EXPECT_TRUE(result_);
3543
3544 // Lose the output surface.
3545 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
3546 GL_GUILTY_CONTEXT_RESET_ARB,
3547 GL_INNOCENT_CONTEXT_RESET_ARB);
3548 break;
3549 case 3:
3550 // With SingleThreadProxy it takes two commits to finally swap after a
3551 // context loss.
3552 case 4:
3553 // The output surface has been recreated.
3554 EXPECT_TRUE(second_context_provider_.get());
3555
3556 num_textures_after_loss_ =
3557 first_context_provider_->TestContext3d()->NumTextures();
3558 break;
3559 }
3560 }
3561
3562 void CheckNumTextures(size_t expected_num_textures) {
3563 EXPECT_EQ(expected_num_textures,
3564 first_context_provider_->TestContext3d()->NumTextures());
3565 EndTest();
3566 }
3567
3568 virtual void AfterTest() OVERRIDE {}
3569
3570 scoped_refptr<TestContextProvider> first_context_provider_;
3571 scoped_refptr<TestContextProvider> second_context_provider_;
3572 size_t num_textures_without_readback_;
3573 size_t num_textures_after_loss_;
3574 FakeContentLayerClient client_;
3575 scoped_refptr<FakeContentLayer> root_;
3576 scoped_refptr<FakeContentLayer> copy_layer_;
3577 scoped_ptr<CopyOutputResult> result_;
3578 };
3579
3580 // No output to copy for delegated renderers.
3581 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3582 LayerTreeHostTestAsyncReadbackLostOutputSurface);
3583
3584 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { 2930 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
3585 public: 2931 public:
3586 virtual void BeginTest() OVERRIDE { 2932 virtual void BeginTest() OVERRIDE {
3587 frame_ = 0; 2933 frame_ = 0;
3588 PostSetNeedsCommitToMainThread(); 2934 PostSetNeedsCommitToMainThread();
3589 } 2935 }
3590 2936
3591 // Round 1: commit + draw 2937 // Round 1: commit + draw
3592 // Round 2: commit only (no draw/swap) 2938 // Round 2: commit only (no draw/swap)
3593 // Round 3: draw only (no commit) 2939 // Round 3: draw only (no commit)
(...skipping 1736 matching lines...) Expand 10 before | Expand all | Expand 10 after
5330 } 4676 }
5331 4677
5332 int commit_count_; 4678 int commit_count_;
5333 int commit_complete_count_; 4679 int commit_complete_count_;
5334 TestSwapPromiseResult swap_promise_result_[3]; 4680 TestSwapPromiseResult swap_promise_result_[3];
5335 }; 4681 };
5336 4682
5337 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); 4683 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
5338 4684
5339 } // namespace cc 4685 } // namespace cc
OLDNEW
« no previous file with comments | « cc/test/test_web_graphics_context_3d.cc ('k') | cc/trees/layer_tree_host_unittest_copyrequest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698