Esempio n. 1
0
bool
InputQueue::AllowScrollHandoff() const
{
  MOZ_ASSERT(CurrentBlock());
  if (CurrentBlock()->AsWheelBlock()) {
    return CurrentBlock()->AsWheelBlock()->AllowScrollHandoff();
  }
  if (CurrentBlock()->AsPanGestureBlock()) {
    return CurrentBlock()->AsPanGestureBlock()->AllowScrollHandoff();
  }
  return true;
}
Esempio n. 2
0
int64
MediaBlockMapReader::ReadFrames(void* buffer, int64 frameCount)
{
    MediaBlock* block = CurrentBlock();

    int64 remaining = frameCount;
    int64 readSize = 0;
    int64 totalRead = 0;

    while (remaining != 0) {
        if (block == NULL || fMap->CountBlocks()-1 > fCurrentIndex)
            block = NextBlock();
        else
            return -1;

        int64 toRead = block->CountFrames();
        if (toRead < remaining) {
            readSize = toRead;
            remaining -= toRead;
        } else {
            readSize = remaining;
            remaining -= readSize;
        }
        totalRead += block->ReadFrames(buffer, readSize);
        buffer += readSize;
    }
    return totalRead;
}
Esempio n. 3
0
PanGestureBlockState*
InputQueue::CurrentPanGestureBlock() const
{
  PanGestureBlockState* block = CurrentBlock()->AsPanGestureBlock();
  MOZ_ASSERT(block);
  return block;
}
Esempio n. 4
0
WheelBlockState*
InputQueue::CurrentWheelBlock() const
{
  WheelBlockState* block = CurrentBlock()->AsWheelBlock();
  MOZ_ASSERT(block);
  return block;
}
Esempio n. 5
0
TouchBlockState*
InputQueue::CurrentTouchBlock() const
{
  TouchBlockState* block = CurrentBlock()->AsTouchBlock();
  MOZ_ASSERT(block);
  return block;
}
Esempio n. 6
0
WheelBlockState*
InputQueue::GetCurrentWheelTransaction() const
{
  if (mInputBlockQueue.IsEmpty()) {
    return nullptr;
  }
  WheelBlockState* block = CurrentBlock()->AsWheelBlock();
  if (!block || !block->InTransaction()) {
    return nullptr;
  }
  return block;
}
Esempio n. 7
0
void
InputQueue::CancelAnimationsForNewBlock(CancelableBlockState* aBlock)
{
  // We want to cancel animations here as soon as possible (i.e. without waiting for
  // content responses) because a finger has gone down and we don't want to keep moving
  // the content under the finger. However, to prevent "future" touchstart events from
  // interfering with "past" animations (i.e. from a previous touch block that is still
  // being processed) we only do this animation-cancellation if there are no older
  // touch blocks still in the queue.
  if (aBlock == CurrentBlock()) {
    aBlock->GetOverscrollHandoffChain()->CancelAnimations(ExcludeOverscroll);
  }
}
Esempio n. 8
0
bool
InputQueue::MaybeHandleCurrentBlock(CancelableBlockState *block,
                                    const InputData& aEvent) {
  if (block == CurrentBlock() && block->IsReadyForHandling()) {
    const RefPtr<AsyncPanZoomController>& target = block->GetTargetApzc();
    INPQ_LOG("current block is ready with target %p preventdefault %d\n",
        target.get(), block->IsDefaultPrevented());
    if (!target || block->IsDefaultPrevented()) {
      return true;
    }
    UpdateActiveApzc(block->GetTargetApzc());
    block->DispatchImmediate(aEvent);
    return true;
  }
  return false;
}
Esempio n. 9
0
int64
MediaBlockMapWriter::WriteFrames(void* buffer, int64 frameCount)
{
    MediaBlock* block = CurrentBlock();

    int64 remaining = frameCount;
    int64 totalWrite = 0;
    int64 offset = 0;
    while (remaining > 0) {

        if (block == NULL || block->CurrentFrame() == MEDIA_BLOCK_MAX_FRAMES) {
            block = NextBlock();

            if (block == NULL)
                block = RequestBlock();
        }

        int64 writeSize = 0;
        int64 freeSize = MEDIA_BLOCK_MAX_FRAMES-block->CurrentFrame();

        printf("Got a block %d available space from block %"
               B_PRId64 " we want to write %" B_PRId64 "\n",
               (int)fCurrentIndex, freeSize, remaining);

        if (freeSize < remaining) {
            writeSize = freeSize;
            remaining -= freeSize;
        } else {
            writeSize = remaining;
            remaining -= writeSize;
        }

        totalWrite += block->WriteFrames(buffer+offset,
                                         writeSize);
        offset += writeSize;
        block->SetFlushed(false);

        printf("Data written %" B_PRId64 "available %"
               B_PRId64 "\n", writeSize,
               MEDIA_BLOCK_MAX_FRAMES - block->CurrentFrame());
    }
    return totalWrite;
}
Esempio n. 10
0
void
InputQueue::ProcessInputBlocks() {
  APZThreadUtils::AssertOnControllerThread();

  do {
    CancelableBlockState* curBlock = CurrentBlock();
    if (!curBlock->IsReadyForHandling()) {
      break;
    }

    INPQ_LOG("processing input block %p; preventDefault %d target %p\n",
        curBlock, curBlock->IsDefaultPrevented(),
        curBlock->GetTargetApzc().get());
    RefPtr<AsyncPanZoomController> target = curBlock->GetTargetApzc();
    // target may be null here if the initial target was unconfirmed and then
    // we later got a confirmed null target. in that case drop the events.
    if (!target) {
      curBlock->DropEvents();
    } else if (curBlock->IsDefaultPrevented()) {
      curBlock->DropEvents();
      target->ResetInputState();
    } else {
      UpdateActiveApzc(curBlock->GetTargetApzc());
      curBlock->HandleEvents();
    }
    MOZ_ASSERT(!curBlock->HasEvents());

    if (mInputBlockQueue.Length() == 1 && curBlock->MustStayActive()) {
      // Some types of blocks (e.g. touch blocks) accumulate events until the
      // next input block is started. Therefore we cannot remove the block from
      // the queue until we have started another block. This block will be
      // removed by SweepDeletedBlocks() whenever a new block is added.
      break;
    }

    // If we get here, we know there are more touch blocks in the queue after
    // |curBlock|, so we can remove |curBlock| and try to process the next one.
    INPQ_LOG("discarding processed %s block %p\n", curBlock->Type(), curBlock);
    mInputBlockQueue.RemoveElementAt(0);
  } while (!mInputBlockQueue.IsEmpty());
}
Esempio n. 11
0
nsEventStatus
InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
                              bool aTargetConfirmed,
                              const MultiTouchInput& aEvent,
                              uint64_t* aOutInputBlockId) {
  TouchBlockState* block = nullptr;
  if (aEvent.mType == MultiTouchInput::MULTITOUCH_START) {
    nsTArray<TouchBehaviorFlags> currentBehaviors;
    bool haveBehaviors = false;
    if (!gfxPrefs::TouchActionEnabled()) {
      haveBehaviors = true;
    } else if (!mInputBlockQueue.IsEmpty() && CurrentBlock()->AsTouchBlock()) {
      haveBehaviors = CurrentTouchBlock()->GetAllowedTouchBehaviors(currentBehaviors);
      // If the behaviours aren't set, but the main-thread response timer on
      // the block is expired we still treat it as though it has behaviors,
      // because in that case we still want to interrupt the fast-fling and
      // use the default behaviours.
      haveBehaviors |= CurrentTouchBlock()->IsContentResponseTimerExpired();
    }

    block = StartNewTouchBlock(aTarget, aTargetConfirmed, false);
    INPQ_LOG("started new touch block %p for target %p\n", block, aTarget.get());

    // XXX using the chain from |block| here may be wrong in cases where the
    // target isn't confirmed and the real target turns out to be something
    // else. For now assume this is rare enough that it's not an issue.
    if (block == CurrentBlock() &&
        aEvent.mTouches.Length() == 1 &&
        block->GetOverscrollHandoffChain()->HasFastFlungApzc() &&
        haveBehaviors) {
      // If we're already in a fast fling, and a single finger goes down, then
      // we want special handling for the touch event, because it shouldn't get
      // delivered to content. Note that we don't set this flag when going
      // from a fast fling to a pinch state (i.e. second finger goes down while
      // the first finger is moving).
      block->SetDuringFastFling();
      block->SetConfirmedTargetApzc(aTarget);
      if (gfxPrefs::TouchActionEnabled()) {
        block->SetAllowedTouchBehaviors(currentBehaviors);
      }
      INPQ_LOG("block %p tagged as fast-motion\n", block);
    }

    CancelAnimationsForNewBlock(block);

    MaybeRequestContentResponse(aTarget, block);
  } else {
    if (!mInputBlockQueue.IsEmpty()) {
      block = mInputBlockQueue.LastElement().get()->AsTouchBlock();
    }

    if (!block) {
      NS_WARNING("Received a non-start touch event while no touch blocks active!");
      return nsEventStatus_eIgnore;
    }

    INPQ_LOG("received new event in block %p\n", block);
  }

  if (aOutInputBlockId) {
    *aOutInputBlockId = block->GetBlockId();
  }

  // Note that the |aTarget| the APZCTM sent us may contradict the confirmed
  // target set on the block. In this case the confirmed target (which may be
  // null) should take priority. This is equivalent to just always using the
  // target (confirmed or not) from the block.
  RefPtr<AsyncPanZoomController> target = block->GetTargetApzc();

  nsEventStatus result = nsEventStatus_eIgnore;

  // XXX calling ArePointerEventsConsumable on |target| may be wrong here if
  // the target isn't confirmed and the real target turns out to be something
  // else. For now assume this is rare enough that it's not an issue.
  if (block->IsDuringFastFling()) {
    INPQ_LOG("dropping event due to block %p being in fast motion\n", block);
    result = nsEventStatus_eConsumeNoDefault;
  } else if (target && target->ArePointerEventsConsumable(block, aEvent.AsMultiTouchInput().mTouches.Length())) {
    result = nsEventStatus_eConsumeDoDefault;
  }
  if (!MaybeHandleCurrentBlock(block, aEvent)) {
    block->AddEvent(aEvent.AsMultiTouchInput());
  }
  return result;
}