Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  IDecodingTask.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "IDecodingTask.h"

#include "nsThreadUtils.h"
#include "mozilla/AppShutdown.h"

#include "Decoder.h"
#include "DecodePool.h"
#include "RasterImage.h"
#include "SurfaceCache.h"

namespace mozilla {

using gfx::IntRect;

namespace image {

///////////////////////////////////////////////////////////////////////////////
// Helpers for sending notifications to the image associated with a decoder.
///////////////////////////////////////////////////////////////////////////////

void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
                                   NotNull<Decoder*> aDecoder) {
  MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode());

  // Capture the decoder's state. If we need to notify asynchronously, it's
  // important that we don't wait until the lambda actually runs to capture the
  // state that we're going to notify. That would both introduce data races on
  // the decoder's state and cause inconsistencies between the NotifyProgress()
  // calls we make off-main-thread and the notifications that RasterImage
  // actually receives, which would cause bugs.
  Progress progress = aDecoder->TakeProgress();
  OrientedIntRect invalidRect = aDecoder->TakeInvalidRect();
  Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount();
  DecoderFlags decoderFlags = aDecoder->GetDecoderFlags();
  SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();

  // Synchronously notify if we can.
  if (NS_IsMainThread() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
    aImage->NotifyProgress(progress, invalidRect, frameCount, decoderFlags,
                           surfaceFlags);
    return;
  }

  // Don't try to dispatch after shutdown, we'll just leak the runnable.
  if (NS_WARN_IF(
          AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownThreads))) {
    return;
  }

  // We're forced to notify asynchronously.
  NotNull<RefPtr<RasterImage>> image = aImage;
  nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
  eventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
                            "IDecodingTask::NotifyProgress",
                            [=]() -> void {
                              image->NotifyProgress(progress, invalidRect,
                                                    frameCount, decoderFlags,
                                                    surfaceFlags);
                            })),
                        NS_DISPATCH_NORMAL);
}

void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
                                         NotNull<Decoder*> aDecoder) {
  MOZ_ASSERT(aDecoder->HasError() || !aDecoder->InFrame(),
             "Decode complete in the middle of a frame?");

  // Capture the decoder's state.
  DecoderFinalStatus finalStatus = aDecoder->FinalStatus();
  ImageMetadata metadata = aDecoder->GetImageMetadata();
  DecoderTelemetry telemetry = aDecoder->Telemetry();
  Progress progress = aDecoder->TakeProgress();
  OrientedIntRect invalidRect = aDecoder->TakeInvalidRect();
  Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount();
  DecoderFlags decoderFlags = aDecoder->GetDecoderFlags();
  SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();

  // Synchronously notify if we can.
  if (NS_IsMainThread() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
    aImage->NotifyDecodeComplete(finalStatus, metadata, telemetry, progress,
                                 invalidRect, frameCount, decoderFlags,
                                 surfaceFlags);
    return;
  }

  // Don't try to dispatch after shutdown, we'll just leak the runnable.
  if (NS_WARN_IF(
          AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownThreads))) {
    return;
  }

  // We're forced to notify asynchronously.
  NotNull<RefPtr<RasterImage>> image = aImage;
  nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
  eventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
                            "IDecodingTask::NotifyDecodeComplete",
                            [=]() -> void {
                              image->NotifyDecodeComplete(
                                  finalStatus, metadata, telemetry, progress,
                                  invalidRect, frameCount, decoderFlags,
                                  surfaceFlags);
                            })),
                        NS_DISPATCH_NORMAL);
}

///////////////////////////////////////////////////////////////////////////////
// IDecodingTask implementation.
///////////////////////////////////////////////////////////////////////////////

void IDecodingTask::Resume() { DecodePool::Singleton()->AsyncRun(this); }

///////////////////////////////////////////////////////////////////////////////
// MetadataDecodingTask implementation.
///////////////////////////////////////////////////////////////////////////////

MetadataDecodingTask::MetadataDecodingTask(NotNull<Decoder*> aDecoder)
    : mMutex("mozilla::image::MetadataDecodingTask"), mDecoder(aDecoder) {
  MOZ_ASSERT(mDecoder->IsMetadataDecode(),
             "Use DecodingTask for non-metadata decodes");
}

void MetadataDecodingTask::Run() {
  MutexAutoLock lock(mMutex);

  LexerResult result = mDecoder->Decode(WrapNotNull(this));

  if (result.is<TerminalState>()) {
    NotifyDecodeComplete(mDecoder->GetImage(), mDecoder);
    return;  // We're done.
  }

  if (result == LexerResult(Yield::NEED_MORE_DATA)) {
    // We can't make any more progress right now. We also don't want to report
    // any progress, because it's important that metadata decode results are
    // delivered atomically. The decoder itself will ensure that we get
    // reenqueued when more data is available; just return for now.
    return;
  }

  MOZ_ASSERT_UNREACHABLE("Metadata decode yielded for an unexpected reason");
}

///////////////////////////////////////////////////////////////////////////////
// AnonymousDecodingTask implementation.
///////////////////////////////////////////////////////////////////////////////

AnonymousDecodingTask::AnonymousDecodingTask(NotNull<Decoder*> aDecoder,
                                             bool aResumable)
    : mDecoder(aDecoder), mResumable(aResumable) {}

void AnonymousDecodingTask::Run() {
  while (true) {
    LexerResult result = mDecoder->Decode(WrapNotNull(this));

    if (result.is<TerminalState>()) {
      return;  // We're done.
    }

    if (result == LexerResult(Yield::NEED_MORE_DATA)) {
      // We can't make any more progress right now. Let the caller decide how to
      // handle it.
      return;
    }

    // Right now we don't do anything special for other kinds of yields, so just
    // keep working.
    MOZ_ASSERT(result.is<Yield>());
  }
}

void AnonymousDecodingTask::Resume() {
  // Anonymous decoders normally get all their data at once. We have tests
  // where they don't; typically in these situations, the test re-runs them
  // manually. However some tests want to verify Resume works, so they will
  // explicitly request this behaviour.
  if (mResumable) {
    RefPtr<AnonymousDecodingTask> self(this);
    NS_DispatchToMainThread(
        NS_NewRunnableFunction("image::AnonymousDecodingTask::Resume",
                               [self]() -> void { self->Run(); }));
  }
}

}  // namespace image
}  // namespace mozilla

95%


¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge